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 { Retargetable = 0x100, 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,
59 VisibilityMask = 0x07 }
62 /// Attributes for a field
64 public enum FieldAttr {Default, Private, FamAndAssem, Assembly,
65 Family, FamOrAssem, Public, Static = 0x10, PublicStatic = 0x16,
66 Initonly = 0x20, Literal = 0x40, Notserialized = 0x80,
67 SpecialName = 0x200, RTSpecialName = 0x400, HasFieldMarshal = 0x1000 }
70 /// Attributes for a method
72 public enum MethAttr { Default, Private, FamAndAssem, Assembly,
73 Family, FamOrAssem, Public, Static = 0x0010, PublicStatic = 0x16,
74 Final = 0x0020, PublicStaticFinal = 0x36, Virtual = 0x0040,
75 PrivateVirtual, PublicVirtual = 0x0046, HideBySig = 0x0080,
76 NewSlot = 0x0100, Strict = 0x200, Abstract = 0x0400, SpecialName = 0x0800,
77 RTSpecialName = 0x1000, SpecialRTSpecialName = 0x1800,
78 HasSecurity = 0x4000, RequireSecObject = 0x8000}
81 /// Attributes for .pinvokeimpl method declarations
83 public enum PInvokeAttr { nomangle = 1, ansi = 2, unicode = 4, autochar = 6,
84 bestfit_on = 0x0010, bestfit_off = 0x0020, bestfit_mask = 0x0030,
85 lasterr = 0x0040, winapi = 0x0100, cdecl = 0x0200,
86 stdcall = 0x0300, thiscall = 0x0400, fastcall = 0x0500,
87 charmaperror_on = 0x1000, charmaperror_off = 0x2000
91 /// Implementation attributes for a method
93 public enum ImplAttr { IL, Native, Runtime = 0x03, Unmanaged = 0x04,
94 ForwardRef = 0x10, PreserveSig = 0x0080, InternalCall = 0x1000,
95 Synchronised = 0x0020, Synchronized = 0x0020, NoInLining = 0x0008, Optil = 0x0002}
98 /// Modes for a parameter
100 public enum ParamAttr { Default, In, Out, Opt = 16, HasDefault = 0x1000, HasFieldMarshal = 0x2000 }
105 public enum Op { nop, breakOp, ldarg_0, ldarg_1, ldarg_2, ldarg_3,
106 ldloc_0, ldloc_1, ldloc_2, ldloc_3, stloc_0, stloc_1, stloc_2, stloc_3,
107 ldnull = 0x14, ldc_i4_m1, ldc_i4_0, ldc_i4_1, ldc_i4_2, ldc_i4_3,
108 ldc_i4_4, ldc_i4_5, ldc_i4_6, ldc_i4_7, ldc_i4_8, dup = 0x25, pop,
109 ret = 0x2A, ldind_i1 = 0x46, ldind_u1, ldind_i2, ldind_u2, ldind_i4,
110 ldind_u4, ldind_i8, ldind_i, ldind_r4, ldind_r8, ldind_ref, stind_ref,
111 stind_i1, stind_i2, stind_i4, stind_i8, stind_r4, stind_r8, add, sub, mul,
112 div, div_un, rem, rem_un, and, or, xor, shl, shr, shr_un, neg, not,
113 conv_i1, conv_i2, conv_i4, conv_i8, conv_r4, conv_r8, conv_u4, conv_u8,
114 conv_r_un = 0x76, throwOp = 0x7A, conv_ovf_i1_un = 0x82, conv_ovf_i2_un,
115 conv_ovf_i4_un, conv_ovf_i8_un, conf_ovf_u1_un, conv_ovf_u2_un,
116 conv_ovf_u4_un, conv_ovf_u8_un, conv_ovf_i_un, conv_ovf_u_un,
117 ldlen = 0x8E, ldelem_i1 = 0x90, ldelem_u1, ldelem_i2, ldelem_u2,
118 ldelem_i4, ldelem_u4, ldelem_i8, ldelem_i, ldelem_r4, ldelem_r8,
119 ldelem_ref, stelem_i, stelem_i1, stelem_i2, stelem_i4, stelem_i8, stelem_r4 = 0xA0, stelem_r8,
120 stelem_ref, conv_ovf_i1 = 0xb3, conv_ovf_u1, conv_ovf_i2, conv_ovf_u2,
121 conv_ovf_i4, conv_ovf_u4, conv_ovf_i8, conv_ovf_u8, ckfinite = 0xC3,
122 conv_u2 = 0xD1, conv_u1, conv_i, conv_ovf_i, conv_ovf_u, add_ovf,
123 add_ovf_un, mul_ovf, mul_ovf_un, sub_ovf, sub_ovf_un, endfinally,
124 stind_i = 0xDF, conv_u, arglist = 0xFE00, ceq, cgt, cgt_un, clt, clt_un,
125 localloc = 0xFE0F, endfilter = 0xFE11, volatile_ = 0xFE13, tail_,
126 cpblk = 0xFE17, initblk, rethrow = 0xFE1A, refanytype = 0xFE1D, readonly_ = 0xFE1E }
129 /// CIL instructions requiring an integer parameter
131 public enum IntOp {ldarg_s = 0x0E, ldarga_s, starg_s, ldloc_s, ldloca_s,
132 stloc_s, ldc_i4_s = 0x1F, ldc_i4, ldarg = 0xFE09,
133 ldarga, starg, ldloc, ldloca, stloc, unaligned = 0xFE12 }
136 /// CIL instructions requiring a field parameter
138 public enum FieldOp {ldfld = 0x7B, ldflda, stfld, ldsfld, ldsflda,
139 stsfld, ldtoken = 0xD0 }
142 /// CIL instructions requiring a method parameter
144 public enum MethodOp {jmp = 0x27, call, callvirt = 0x6F, newobj = 0x73,
145 ldtoken = 0xD0, ldftn = 0xFE06, ldvirtfn }
148 /// CIL instructions requiring a type parameter
150 public enum TypeOp {cpobj = 0x70, ldobj, castclass = 0x74, isinst,
151 unbox = 0x79, stobj = 0x81, box = 0x8C, newarr,
152 ldelema = 0x8F, refanyval = 0xC2, mkrefany = 0xC6,
153 ldtoken = 0xD0, initobj = 0xFE15, constrained = 0xFE16,
154 sizeOf = 0xFE1C, ldelem = 0xA3, stelem = 0xA4, unbox_any }
157 /// CIL branch instructions
159 public enum BranchOp {
161 br_s = 0x2B, brfalse_s, brtrue_s, beq_s, bge_s, bgt_s,
162 ble_s, blt_s, bne_un_s, bge_un_s, bgt_un_s, ble_un_s, blt_un_s,
164 br = 0x38, brfalse, brtrue, beq, bge, bgt, ble, blt,
165 bne_un, bge_un, bgt_un, ble_un, blt_un,
167 leave = 0xDD, leave_s }
170 /// Index for all the tables in the meta data
172 public enum MDTable { Module, TypeRef, TypeDef, Field = 0x04, Method = 0x06,
173 Param = 0x08, InterfaceImpl, MemberRef, Constant, CustomAttribute,
174 FieldMarshal, DeclSecurity, ClassLayout, FieldLayout, StandAloneSig,
175 EventMap, Event = 0x14, PropertyMap, Property = 0x17, MethodSemantics,
176 MethodImpl, ModuleRef, TypeSpec, ImplMap, FieldRVA, Assembly = 0x20,
177 AssemblyProcessor, AssemblyOS, AssemblyRef, AssemblyRefProcessor,
178 AssemblyRefOS, File, ExportedType, ManifestResource, NestedClass,
179 GenericParam, MethodSpec, GenericParamConstraint }
181 public enum SafeArrayType { int16 = 2, int32, float32, float64,
182 currency, date, bstr, dispatch, error, boolean, variant, unknown,
183 Decimal, int8 = 16, uint8, uint16, uint32, Int = 22, UInt }
185 internal enum CIx { TypeDefOrRef, HasConst, HasCustomAttr, HasFieldMarshal,
186 HasDeclSecurity, MemberRefParent, HasSemantics, MethodDefOrRef,
187 MemberForwarded, Implementation, CustomAttributeType, ResolutionScope,
188 TypeOrMethodDef, MaxCIx }
190 internal enum MapType { eventMap, propertyMap, nestedClass }
192 public enum ValueClass { ValueType, Enum }
194 public enum GenParamType : byte {
195 Var = 0x13, MVar = 0x1E
199 public enum GenericParamAttributes : ushort {
200 VarianceMask = 0x0003,
203 Contravariant = 0x0002,
205 SpecialConstraintMask = 0x001c,
206 ReferenceTypeConstraint = 0x0004,
207 NotNullableValueTypeConstraint = 0x0008,
208 DefaultConstructorConstrait = 0x0010
211 /* Taken from Mono.Cecil */
212 public enum SecurityAction : short {
226 NonCasLinkDemand = 14,
227 NonCasInheritance = 15,
228 LinkDemandChoice = 16,
229 InheritDemandChoice = 17,
235 /**************************************************************************/
237 /// Base class for all Meta Data table elements
240 public abstract class MetaDataElement: IComparable {
241 protected ArrayList customAttributes;
242 private uint row = 0;
243 protected bool done = false;
244 protected MDTable tabIx;
245 protected bool sortTable = false;
247 private bool has_custom_attrs = false;
249 internal MetaDataElement() { }
260 public bool HasCustomAttr {
261 get { return has_custom_attrs; }
262 set { has_custom_attrs = value; }
265 internal virtual uint GetCodedIx(CIx code) { return 0; }
268 /// Add a custom attribute to this item
270 /// <param name="ctorMeth">the constructor method for this attribute</param>
271 /// <param name="val">the byte value of the parameters</param>
272 public void AddCustomAttribute(Method ctorMeth, byte[] val)
274 if (customAttributes == null) {
275 customAttributes = new ArrayList();
277 customAttributes.Add(new CustomAttribute(this,ctorMeth,val));
281 /// Add a custom attribute to this item
283 /// <param name="ctorMeth">the constructor method for this attribute</param>
284 /// <param name="val">the constant values of the parameters</param>
285 public void AddCustomAttribute(Method ctorMeth, Constant[] cVals)
287 if (customAttributes == null) {
288 customAttributes = new ArrayList();
290 // customAttributes.Add(new CustomAttribute(this,ctorMeth,cVals));
293 internal uint Token()
295 return (((uint)tabIx << 24) | row);
298 internal virtual void BuildTables(MetaData md)
303 internal virtual uint Size(MetaData md)
308 internal virtual void Write(FileImage output) { }
310 internal virtual uint SortKey()
312 throw new PEFileException("Trying to sort table of " + this);
316 internal virtual uint SortKey2()
321 public int CompareTo(object obj)
323 uint otherKey = ((MetaDataElement)obj).SortKey();
324 uint thisKey = SortKey();
326 if (thisKey == otherKey) {
328 otherKey = ((MetaDataElement)obj).SortKey2();
329 thisKey = SortKey2();
330 if (thisKey == otherKey)
332 if (thisKey < otherKey)
336 if (thisKey < otherKey) return -1;
343 /**************************************************************************/
345 /// Layout information for a class (.class [sequential | explicit])
347 internal class ClassLayout : MetaDataElement {
353 internal ClassLayout(int pack, int cSize, ClassDef par)
355 packSize = (ushort)pack;
356 classSize = (uint)cSize;
358 tabIx = MDTable.ClassLayout;
361 internal sealed override uint Size(MetaData md)
363 return 6 + md.TableIndexSize(MDTable.TypeDef);
366 internal sealed override void Write(FileImage output)
368 output.Write(packSize);
369 output.Write(classSize);
370 output.WriteIndex(MDTable.TypeDef,parent.Row);
375 /**************************************************************************/
377 /// Summary description for ConstantElem.
379 internal class ConstantElem : MetaDataElement {
381 MetaDataElement parent;
385 internal ConstantElem(MetaDataElement parent, Constant val)
387 this.parent = parent;
389 tabIx = MDTable.Constant;
393 internal override uint SortKey()
395 return (parent.Row << MetaData.CIxShiftMap[(uint)CIx.HasConst])
396 | parent.GetCodedIx(CIx.HasConst);
399 internal sealed override void BuildTables(MetaData md)
402 valIx = cValue.GetBlobIndex(md);
406 internal void AddToBlob(BinaryWriter bw)
411 internal sealed override uint Size(MetaData md)
413 return 2 + md.CodedIndexSize(CIx.HasConst) + md.BlobIndexSize();
416 internal sealed override void Write(FileImage output)
418 output.Write(cValue.GetTypeIndex());
419 output.Write((byte)0);
420 output.WriteCodedIndex(CIx.HasConst,parent);
421 output.BlobIndex(valIx);
425 /**************************************************************************/
427 /// Descriptor for a Custom Attribute (.custom)
430 public class CustomAttribute : MetaDataElement {
432 MetaDataElement parent;
438 ArrayList names, vals;
440 internal CustomAttribute(MetaDataElement paren, Method constrType,
445 tabIx = MDTable.CustomAttribute;
447 byteVal = ConstantToByteArray (val);
450 static byte[] ConstantToByteArray (Constant c)
452 var bac = c as ByteArrConst;
456 var sc = c as StringConst;
458 string value = sc.val;
460 throw new NotImplementedException ();
462 var ms = new MemoryStream ();
467 var buf = Encoding.UTF8.GetBytes (value);
468 MetaData.CompressNum ((uint) buf.Length, ms);
469 var byteVal = ms.ToArray ();
470 System.Array.Resize (ref byteVal, (int) ms.Length + buf.Length + 2);
471 System.Array.Copy (buf, 0, byteVal, ms.Length, buf.Length);
475 throw new NotImplementedException (c.GetType ().ToString ());
478 internal CustomAttribute(MetaDataElement paren, Method constrType,
482 tabIx = MDTable.CustomAttribute;
486 internal override uint SortKey()
488 return (parent.Row << MetaData.CIxShiftMap[(uint)CIx.HasCustomAttr])
489 | parent.GetCodedIx(CIx.HasCustomAttr);
492 public void AddFieldOrProp(string name, Constant val)
495 names = new ArrayList();
496 vals = new ArrayList();
502 internal sealed override void BuildTables(MetaData md)
504 md.AddToTable(MDTable.CustomAttribute, this);
505 if (byteVal == null) {
510 BinaryWriter bw = new BinaryWriter(new MemoryStream());
512 MemoryStream str = (MemoryStream)bw.BaseStream;
513 valIx = md.AddToBlobHeap(str.ToArray());
516 internal sealed override uint Size(MetaData md)
518 return md.CodedIndexSize(CIx.HasCustomAttr) + md.CodedIndexSize(CIx.CustomAttributeType) + md.BlobIndexSize();
521 internal sealed override void Write(FileImage output)
523 output.WriteCodedIndex(CIx.HasCustomAttr,parent);
524 output.WriteCodedIndex(CIx.CustomAttributeType,type);
525 output.BlobIndex(valIx);
530 /**************************************************************************/
532 /// Descriptor for security permissions for a class or a method
535 public abstract class BaseDeclSecurity : MetaDataElement {
538 MetaDataElement parent;
541 internal BaseDeclSecurity(MetaDataElement paren, ushort act)
545 tabIx = MDTable.DeclSecurity;
548 internal override uint SortKey()
550 return (parent.Row << MetaData.CIxShiftMap[(uint)CIx.HasDeclSecurity])
551 | parent.GetCodedIx(CIx.HasDeclSecurity);
554 internal sealed override uint Size(MetaData md)
556 return 2 + md.CodedIndexSize(CIx.HasDeclSecurity) + md.BlobIndexSize();
559 internal sealed override void BuildTables(MetaData md)
563 BinaryWriter bw = new BinaryWriter (new MemoryStream ());
564 md.AddToTable (MDTable.DeclSecurity, this);
565 MemoryStream str = (MemoryStream)bw.BaseStream;
567 permissionIx = md.AddToBlobHeap(str.ToArray());
572 internal abstract void WriteSig (BinaryWriter bw);
574 internal sealed override void Write(FileImage output)
576 output.Write(action);
577 output.WriteCodedIndex(CIx.HasDeclSecurity,parent);
578 output.BlobIndex(permissionIx);
583 public class DeclSecurity : BaseDeclSecurity {
587 internal DeclSecurity(MetaDataElement paren, ushort act, byte [] val)
593 internal override void WriteSig (BinaryWriter bw)
600 public class DeclSecurity_20 : BaseDeclSecurity {
604 internal DeclSecurity_20 (MetaDataElement paren, ushort act, PermissionSet ps)
610 internal override void WriteSig (BinaryWriter bw)
616 public class PermissionMember {
618 MemberTypes member_type;
623 public PermissionMember (MemberTypes member_type, PEAPI.Type type, string name, object value)
625 this.member_type = member_type;
631 public void Write (BinaryWriter bw)
635 if (member_type == MemberTypes.Field)
636 bw.Write ((byte) 0x53);
639 bw.Write ((byte) 0x54);
641 if (type is PrimitiveType) {
642 bw.Write (type.GetTypeIndex ());
645 bw.Write ((byte) 0x55); //ENUM
647 b = Encoding.UTF8.GetBytes (((ClassRef) type).TypeName ());
648 MetaData.CompressNum ((uint) b.Length, (MemoryStream) bw.BaseStream);
652 b = Encoding.UTF8.GetBytes (name);
653 MetaData.CompressNum ((uint) b.Length, (MemoryStream) bw.BaseStream);
656 ((Constant) value).Write (bw);
661 public class Permission
669 public Permission (PEAPI.Type type, string name)
675 public void AddMember (PEAPI.PermissionMember member)
678 members = new ArrayList ();
680 members.Add (member);
683 public void Write (BinaryWriter bw)
685 byte [] b = Encoding.UTF8.GetBytes (name);
686 MetaData.CompressNum ((uint) b.Length, (MemoryStream) bw.BaseStream);
689 BinaryWriter perm_writer = new BinaryWriter (new MemoryStream (), Encoding.Unicode);
690 MemoryStream str = (MemoryStream) perm_writer.BaseStream;
692 MetaData.CompressNum ((uint) members.Count, str);//number of params
693 foreach (PermissionMember member in members)
694 member.Write (perm_writer);
696 bw.Write ((byte) str.Length); //(optional) parameters length
697 bw.Write (str.ToArray ());
701 public class PermissionSet
703 PEAPI.SecurityAction sec_action;
704 ArrayList permissions;
706 public PermissionSet (PEAPI.SecurityAction sec_action)
708 this.sec_action = sec_action;
711 public void AddPermission (PEAPI.Permission perm)
713 if (permissions == null)
714 permissions = new ArrayList ();
716 permissions.Add (perm);
719 public void Write (BinaryWriter bw)
721 bw.Write ((byte) 0x2e);
722 MetaData.CompressNum ((uint) permissions.Count, (MemoryStream) bw.BaseStream);
724 foreach (Permission perm in permissions)
730 /**************************************************************************/
732 /// Descriptor for layout information for a field
735 public class FieldLayout : MetaDataElement {
740 internal FieldLayout(Field field, uint offset)
743 this.offset = offset;
744 tabIx = MDTable.FieldLayout;
747 internal sealed override uint Size(MetaData md)
749 return 4 + md.TableIndexSize(MDTable.Field);
752 internal sealed override void Write(FileImage output)
754 output.Write(offset);
755 output.WriteIndex(MDTable.Field,field.Row);
760 /*****************************************************************************/
762 /// Marshalling information for a field or param
764 public class FieldMarshal : MetaDataElement {
766 MetaDataElement field;
770 internal FieldMarshal(MetaDataElement field, NativeType nType)
774 tabIx = MDTable.FieldMarshal;
777 internal override uint SortKey()
779 return (field.Row << MetaData.CIxShiftMap[(uint)CIx.HasFieldMarshal])
780 | field.GetCodedIx(CIx.HasFieldMarshal);
783 internal sealed override void BuildTables(MetaData md)
786 ntIx = md.AddToBlobHeap(nt.ToBlob());
790 internal sealed override uint Size(MetaData md)
792 return md.CodedIndexSize(CIx.HasFieldMarshal) + md.BlobIndexSize();
795 internal sealed override void Write(FileImage output)
797 output.WriteCodedIndex(CIx.HasFieldMarshal,field);
798 output.BlobIndex(ntIx);
803 /**************************************************************************/
805 /// Descriptor for the address of a field's value in the PE file
807 public class FieldRVA : MetaDataElement {
812 internal FieldRVA(Field field, DataConstant data)
816 tabIx = MDTable.FieldRVA;
819 internal sealed override void BuildTables(MetaData md)
826 internal sealed override uint Size(MetaData md)
828 return 4 + md.TableIndexSize(MDTable.Field);
831 internal sealed override void Write(FileImage output)
833 output.WriteDataRVA(data.DataOffset);
834 output.WriteIndex(MDTable.Field,field.Row);
839 /**************************************************************************/
841 /// Descriptor for a file referenced in THIS assembly/module (.file)
843 public class FileRef : MetaDataElement {
845 private static readonly uint NoMetaData = 0x1;
846 uint nameIx = 0, hashIx = 0;
848 protected string name;
850 internal FileRef(string name, byte[] hashBytes, bool metaData,
851 bool entryPoint, MetaData md) {
852 if (!metaData) flags = NoMetaData;
853 if (entryPoint) md.SetEntryPoint(this);
855 nameIx = md.AddToStringsHeap(name);
856 hashIx = md.AddToBlobHeap(hashBytes);
857 tabIx = MDTable.File;
860 internal FileRef(uint nameIx, byte[] hashBytes, bool metaData,
861 bool entryPoint, MetaData md) {
862 if (!metaData) flags = NoMetaData;
863 if (entryPoint) md.SetEntryPoint(this);
864 this.nameIx = nameIx;
865 hashIx = md.AddToBlobHeap(hashBytes);
866 tabIx = MDTable.File;
869 internal sealed override uint Size(MetaData md)
871 return 4 + md.StringsIndexSize() + md.BlobIndexSize();
874 internal sealed override void BuildTables(MetaData md)
876 md.AddToTable(MDTable.File,this);
879 internal sealed override void Write(FileImage output)
882 output.StringsIndex(nameIx);
883 output.BlobIndex(hashIx);
886 internal sealed override uint GetCodedIx(CIx code)
889 case (CIx.HasCustomAttr) : return 16;
890 case (CIx.Implementation) : return 0;
896 /**************************************************************************/
898 /// Descriptor for pinvoke information for a method NOT YET IMPLEMENTED
900 public class ImplMap : MetaDataElement {
902 private static readonly ushort NoMangle = 0x01;
907 ModuleRef importScope;
909 internal ImplMap(ushort flag, Method implMeth, string iName, ModuleRef mScope)
914 importScope = mScope;
915 tabIx = MDTable.ImplMap;
916 if (iName == null) flags |= NoMangle;
917 //throw(new NotYetImplementedException("PInvoke "));
920 internal override uint SortKey()
922 return (meth.Row << MetaData.CIxShiftMap[(uint)CIx.MemberForwarded])
923 | meth.GetCodedIx(CIx.MemberForwarded);
926 internal sealed override void BuildTables(MetaData md)
929 iNameIx = md.AddToStringsHeap(importName);
933 internal sealed override uint Size(MetaData md)
935 return 2+ md.CodedIndexSize(CIx.MemberForwarded) +
936 md.StringsIndexSize() + md.TableIndexSize(MDTable.ModuleRef);
939 internal sealed override void Write(FileImage output)
942 output.WriteCodedIndex(CIx.MemberForwarded,meth);
943 output.StringsIndex(iNameIx);
944 output.WriteIndex(MDTable.ModuleRef,importScope.Row);
949 /**************************************************************************/
951 public class GenericParameter : MetaDataElement {
953 MetaDataElement owner;
958 GenericParamAttributes attr;
960 internal GenericParameter (ClassDef owner, MetaData metadata,
961 short index, string name, GenericParamAttributes attr) : this (owner, metadata, index, name, attr, true)
965 internal GenericParameter (MethodDef owner, MetaData metadata,
966 short index, string name, GenericParamAttributes attr) : this (owner, metadata, index, name, attr, true)
970 private GenericParameter (MetaDataElement owner, MetaData metadata,
971 short index, string name, GenericParamAttributes attr, bool nadda) {
973 this.metadata = metadata;
975 tabIx = MDTable.GenericParam;
980 internal override uint SortKey()
982 return (owner.Row << MetaData.CIxShiftMap[(uint)CIx.TypeOrMethodDef])
983 | owner.GetCodedIx(CIx.TypeOrMethodDef);
986 internal override uint SortKey2 ()
991 public void AddConstraint (Type constraint)
993 metadata.AddToTable (MDTable.GenericParamConstraint,
994 new GenericParamConstraint (this, constraint));
997 internal sealed override uint Size(MetaData md)
1000 md.CodedIndexSize(CIx.TypeOrMethodDef) +
1001 md.StringsIndexSize ());
1004 internal sealed override void BuildTables(MetaData md)
1007 nameIx = md.AddToStringsHeap(name);
1011 internal sealed override void Write(FileImage output)
1013 output.Write ((short) index);
1014 output.Write ((short) attr);
1015 output.WriteCodedIndex(CIx.TypeOrMethodDef, owner);
1016 output.StringsIndex (nameIx);
1019 internal sealed override uint GetCodedIx(CIx code)
1022 case (CIx.HasCustomAttr) : return 19;
1029 internal class GenericParamConstraint : MetaDataElement {
1031 GenericParameter param;
1034 public GenericParamConstraint (GenericParameter param, Type type)
1038 tabIx = MDTable.GenericParamConstraint;
1041 internal override uint SortKey()
1046 internal sealed override uint Size(MetaData md)
1048 return (uint) (md.TableIndexSize(MDTable.GenericParam) +
1049 md.CodedIndexSize(CIx.TypeDefOrRef));
1052 internal sealed override void Write(FileImage output)
1054 output.WriteIndex(MDTable.GenericParam, param.Row);
1055 output.WriteCodedIndex(CIx.TypeDefOrRef, type);
1060 internal class MethodSpec : Method {
1063 GenericMethodSig g_sig;
1066 internal MethodSpec (Method meth, GenericMethodSig g_sig) : base ("")
1070 tabIx = MDTable.MethodSpec;
1073 internal override uint GetSigIx (MetaData md)
1075 throw new Exception ("Should not be used.");
1078 public override void AddCallConv (CallConv cconv)
1080 throw new Exception ("Should not be used.");
1083 internal sealed override void BuildTables (MetaData md)
1086 sidx = g_sig.GetSigIx (md);
1090 internal sealed override uint Size (MetaData md)
1092 return (uint) (md.CodedIndexSize(CIx.MethodDefOrRef) +
1093 md.BlobIndexSize ());
1096 internal sealed override void Write (FileImage output)
1098 output.WriteCodedIndex (CIx.MethodDefOrRef, meth);
1099 output.BlobIndex (sidx);
1102 internal sealed override void TypeSig (MemoryStream sig)
1104 throw new Exception ("Should not be used.");
1108 /**************************************************************************/
1110 /// Descriptor for interface implemented by a class
1112 public class InterfaceImpl: MetaDataElement {
1117 internal InterfaceImpl(ClassDef theClass, Class theInterface)
1119 this.theClass = theClass;
1120 this.theInterface = theInterface;
1121 tabIx = MDTable.InterfaceImpl;
1124 internal sealed override uint Size(MetaData md)
1126 return md.TableIndexSize(MDTable.TypeDef) +
1127 md.CodedIndexSize(CIx.TypeDefOrRef);
1130 internal sealed override void Write(FileImage output)
1132 output.WriteIndex(MDTable.TypeDef,theClass.Row);
1133 output.WriteCodedIndex(CIx.TypeDefOrRef,theInterface);
1136 internal sealed override uint GetCodedIx(CIx code) { return 5; }
1138 internal override uint SortKey ()
1140 return (theClass.Row << MetaData.CIxShiftMap[(uint)CIx.TypeDefOrRef])
1141 | theClass.GetCodedIx (CIx.TypeDefOrRef);
1146 /**************************************************************************/
1148 /// Descriptor for resources used in this PE file
1151 public class ManifestResource : MetaDataElement {
1153 public static readonly uint PublicResource = 0x1;
1154 public static readonly uint PrivateResource = 0x2;
1157 MetaDataElement rRef;
1161 byte [] resourceBytes;
1163 public ManifestResource (string name, byte[] resBytes, uint flags)
1165 InitResource (name, flags);
1166 this.resourceBytes = resBytes;
1169 public ManifestResource(string name, uint flags, FileRef fileRef)
1171 InitResource (name, flags);
1175 public ManifestResource(string name, uint flags, FileRef fileRef,
1177 InitResource (name, flags);
1179 fileOffset = fileIx;
1182 public ManifestResource(string name, uint flags, AssemblyRef assemRef)
1184 InitResource (name, flags);
1188 internal ManifestResource (ManifestResource mres)
1190 mrName = mres.mrName;
1193 fileOffset = mres.fileOffset;
1194 resourceBytes = mres.resourceBytes;
1197 private void InitResource (string name, uint flags)
1201 tabIx = MDTable.ManifestResource;
1204 internal sealed override void BuildTables(MetaData md)
1207 md.AddToTable (MDTable.ManifestResource, this);
1208 nameIx = md.AddToStringsHeap(mrName);
1209 if (resourceBytes != null) {
1211 throw new PEFileException ("Manifest Resource has byte value and file reference");
1212 fileOffset = md.AddResource(resourceBytes);
1215 throw new PEFileException ("Manifest Resource has no implementation or value");
1216 rRef.BuildTables (md);
1222 internal sealed override uint Size(MetaData md)
1224 return 8 + md.StringsIndexSize() +
1225 md.CodedIndexSize(CIx.Implementation);
1228 internal sealed override void Write(FileImage output)
1230 output.Write(fileOffset);
1231 output.Write(flags);
1232 output.StringsIndex(nameIx);
1233 output.WriteCodedIndex(CIx.Implementation,rRef);
1236 internal sealed override uint GetCodedIx(CIx code) { return 18; }
1238 public string Name {
1239 get { return mrName; }
1240 set { mrName = value; }
1244 /**************************************************************************/
1246 /// Base class for elements in the PropertyMap, EventMap and
1247 /// NestedClass MetaData tables
1249 public class MapElem : MetaDataElement {
1255 internal MapElem(ClassDef par, uint elIx, MDTable elemTab)
1259 elemTable = elemTab;
1262 internal sealed override uint Size(MetaData md)
1264 return md.TableIndexSize(MDTable.TypeDef) + md.TableIndexSize(elemTable);
1267 internal sealed override void Write(FileImage output)
1269 output.WriteIndex(MDTable.TypeDef,parent.Row);
1270 output.WriteIndex(elemTable,elemIx);
1274 /**************************************************************************/
1276 /// Descriptor for an overriding method (.override)
1278 public class MethodImpl : MetaDataElement {
1281 Method header, body;
1283 internal MethodImpl(ClassDef par, Method decl, Method bod)
1288 tabIx = MDTable.MethodImpl;
1291 internal sealed override uint Size(MetaData md)
1293 return md.TableIndexSize(MDTable.TypeDef) + 2 * md.CodedIndexSize(CIx.MethodDefOrRef);
1296 internal sealed override void Write(FileImage output)
1298 output.WriteIndex(MDTable.TypeDef,parent.Row);
1299 output.WriteCodedIndex(CIx.MethodDefOrRef,body);
1300 output.WriteCodedIndex(CIx.MethodDefOrRef,header);
1305 /**************************************************************************/
1307 /// Descriptor for Property and Event methods
1309 public class MethodSemantics : MetaDataElement {
1311 Feature.MethodType type;
1313 Feature eventOrProp;
1315 internal MethodSemantics(Feature.MethodType mType, MethodDef method, Feature feature)
1319 eventOrProp = feature;
1320 tabIx = MDTable.MethodSemantics;
1323 internal override uint SortKey()
1325 return (eventOrProp.Row << MetaData.CIxShiftMap [(uint)CIx.HasSemantics])
1326 | eventOrProp.GetCodedIx (CIx.HasSemantics);
1329 internal sealed override uint Size(MetaData md)
1331 return 2 + md.TableIndexSize(MDTable.Method) + md.CodedIndexSize(CIx.HasSemantics);
1334 internal sealed override void Write(FileImage output)
1336 output.Write((ushort)type);
1337 output.WriteIndex(MDTable.Method,meth.Row);
1338 output.WriteCodedIndex(CIx.HasSemantics,eventOrProp);
1343 /**************************************************************************/
1345 /// Descriptor for a parameter of a method defined in this assembly/module
1347 public class Param : MetaDataElement {
1352 internal ushort seqNo = 0;
1354 ConstantElem defaultVal;
1356 FieldMarshal marshalInfo;
1359 /// Create a new parameter for a method
1361 /// <param name="mode">param mode (in, out, opt)</param>
1362 /// <param name="parName">parameter name</param>
1363 /// <param name="parType">parameter type</param>
1364 public Param(ParamAttr mode, string parName, Type parType)
1368 parMode = (ushort)mode;
1369 tabIx = MDTable.Param;
1372 public bool HasMarshalInfo {
1373 get { return marshalInfo != null; }
1377 /// Add a default value to this parameter
1379 /// <param name="c">the default value for the parameter</param>
1380 public void AddDefaultValue(Constant cVal)
1382 defaultVal = new ConstantElem(this,cVal);
1383 parMode |= (ushort) ParamAttr.HasDefault;
1387 /// Add marshalling information about this parameter
1389 public void AddMarshallInfo(NativeType marshallType)
1391 parMode |= (ushort) ParamAttr.HasFieldMarshal;
1392 marshalInfo = new FieldMarshal(this,marshallType);
1395 internal Type GetParType() { return pType; }
1397 internal sealed override void BuildTables(MetaData md)
1400 nameIx = md.AddToStringsHeap(pName);
1401 if (defaultVal != null) {
1402 md.AddToTable(MDTable.Constant,defaultVal);
1403 defaultVal.BuildTables(md);
1405 if (marshalInfo != null) {
1406 md.AddToTable(MDTable.FieldMarshal,marshalInfo);
1407 marshalInfo.BuildTables(md);
1412 internal void TypeSig(MemoryStream str)
1417 internal sealed override uint Size(MetaData md)
1419 return 4 + md.StringsIndexSize();
1422 internal sealed override void Write(FileImage output)
1424 output.Write(parMode);
1425 output.Write(seqNo);
1426 output.StringsIndex(nameIx);
1429 internal sealed override uint GetCodedIx(CIx code)
1432 case (CIx.HasCustomAttr) : return 4;
1433 case (CIx.HasConst) : return 1;
1434 case (CIx.HasFieldMarshal) : return 1;
1441 /**************************************************************************/
1442 public abstract class Signature : MetaDataElement {
1444 protected uint sigIx;
1446 internal Signature()
1448 tabIx = MDTable.StandAloneSig;
1451 internal sealed override uint Size(MetaData md)
1453 return md.BlobIndexSize();
1456 internal sealed override void Write(FileImage output)
1458 output.BlobIndex(sigIx);
1461 internal sealed override uint GetCodedIx(CIx code) { return (uint)tabIx; }
1465 /**************************************************************************/
1466 public class TypeSpec : MetaDataElement {
1469 internal TypeSpec(Type aType, MetaData md)
1471 MemoryStream sig = new MemoryStream();
1473 sigIx = md.AddToBlobHeap(sig.ToArray());
1474 tabIx = MDTable.TypeSpec;
1477 internal sealed override uint GetCodedIx(CIx code)
1480 case (CIx.TypeDefOrRef) : return 2;
1481 case (CIx.HasCustomAttr) : return 13;
1482 case (CIx.MemberRefParent) : return 4;
1487 internal override uint Size(MetaData md)
1489 return md.BlobIndexSize();
1492 internal sealed override void Write(FileImage output)
1494 //Console.WriteLine("Writing the blob index for a TypeSpec");
1495 output.BlobIndex(sigIx);
1500 /**************************************************************************/
1502 /// Base class for all IL types
1504 public abstract class Type : MetaDataElement {
1505 protected byte typeIndex;
1506 protected TypeSpec typeSpec;
1508 internal Type(byte tyIx) { typeIndex = tyIx; }
1510 internal byte GetTypeIndex() { return typeIndex; }
1511 internal void SetTypeIndex (byte b) { typeIndex = b; }
1513 internal virtual MetaDataElement GetTypeSpec(MetaData md)
1515 if (typeSpec == null) {
1516 typeSpec = new TypeSpec(this,md);
1517 md.AddToTable(MDTable.TypeSpec,typeSpec);
1522 internal virtual void TypeSig(MemoryStream str)
1524 throw(new TypeSignatureException(this.GetType().AssemblyQualifiedName +
1525 " doesn't have a type signature!!"));
1529 public class ClassRefInst : Type {
1532 private bool is_value;
1534 public ClassRefInst (Type type, bool is_value) : base (PrimitiveType.Class.GetTypeIndex ())
1537 this.is_value = is_value;
1539 typeIndex = PrimitiveType.ValueType.GetTypeIndex ();
1540 tabIx = MDTable.TypeSpec;
1543 internal sealed override void TypeSig(MemoryStream str)
1549 /**************************************************************************/
1551 /// The base descriptor for a class
1553 public abstract class Class : Type {
1555 protected int row = 0;
1556 public string name, nameSpace;
1557 protected uint nameIx, nameSpaceIx;
1558 protected MetaData _metaData;
1559 internal Class(string nameSpaceName, string className, MetaData md)
1560 : base(PrimitiveType.Class.GetTypeIndex ())
1562 nameSpace = nameSpaceName;
1564 nameIx = md.AddToStringsHeap(name);
1565 nameSpaceIx = md.AddToStringsHeap(nameSpace);
1569 internal Class(uint nsIx, uint nIx) : base(PrimitiveType.Class.GetTypeIndex ())
1575 internal Class (byte typeIndex) : base (typeIndex)
1577 nameSpace = "Should not be used";
1578 name = "Should not be used";
1581 internal virtual uint TypeDefOrRefToken() { return 0; }
1583 internal virtual void MakeValueClass(ValueClass vClass)
1585 typeIndex = PrimitiveType.ValueType.GetTypeIndex ();
1588 internal virtual string TypeName()
1590 return (nameSpace + "." + name);
1593 internal override MetaDataElement GetTypeSpec(MetaData md)
1599 /**************************************************************************/
1600 // This Class produces entries in the TypeDef table of the MetaData
1601 // in the PE meta data.
1603 // NOTE: Entry 0 in TypeDef table is always the pseudo class <module>
1604 // which is the parent for functions and variables declared a module level
1607 /// The descriptor for a class defined in the IL (.class) in the current assembly/module
1610 public class ClassDef : Class {
1613 ArrayList fields = new ArrayList();
1614 ArrayList methods = new ArrayList();
1616 ArrayList properties;
1617 bool typeIndexChecked = true;
1618 uint fieldIx = 0, methodIx = 0;
1621 ClassDef parentClass;
1624 internal ClassDef(TypeAttr attrSet, string nsName, string name,
1625 MetaData md) : base(nsName, name, md)
1628 if (! ((nsName == "" && name == "<Module>") || (nsName == "System" && name == "Object")) ) {
1629 superType = metaData.mscorlib.GetSpecialSystemClass(PrimitiveType.Object);
1631 flags = (uint)attrSet;
1632 tabIx = MDTable.TypeDef;
1635 internal void SetSuper(Class sClass)
1638 if (! (sClass is GenericTypeInst))
1639 typeIndexChecked = false;
1642 internal override void MakeValueClass(ValueClass vClass)
1644 if (vClass == ValueClass.Enum)
1645 superType = metaData.mscorlib.EnumType();
1647 superType = metaData.mscorlib.ValueType();
1649 typeIndex = PrimitiveType.ValueType.GetTypeIndex ();
1652 public void SpecialNoSuper()
1658 /// Add an attribute to this class
1660 /// <param name="ta">the attribute to be added</param>
1661 public void AddAttribute(TypeAttr ta)
1667 /// Add an interface that is implemented by this class
1669 /// <param name="iFace">the interface that is implemented</param>
1670 public void AddImplementedInterface(Class iFace)
1672 metaData.AddToTable(MDTable.InterfaceImpl,new InterfaceImpl(this,iFace));
1676 /// Add a named generic type parameter
1678 public GenericParameter AddGenericParameter (short index, string name)
1680 return AddGenericParameter (index, name, 0);
1684 /// Add a named generic type parameter with attributes
1686 public GenericParameter AddGenericParameter (short index, string name, GenericParamAttributes attr)
1688 GenericParameter gp = new GenericParameter (this, metaData, index, name, attr);
1689 metaData.AddToTable (MDTable.GenericParam, gp);
1694 /// Add a field to this class
1696 /// <param name="name">field name</param>
1697 /// <param name="fType">field type</param>
1698 /// <returns>a descriptor for this new field</returns>
1699 public FieldDef AddField(string name, Type fType)
1701 FieldDef field = new FieldDef(name,fType);
1707 /// Add a field to this class
1709 /// <param name="fAtts">attributes for this field</param>
1710 /// <param name="name">field name</param>
1711 /// <param name="fType">field type</param>
1712 /// <returns>a descriptor for this new field</returns>
1713 public FieldDef AddField(FieldAttr fAtts, string name, Type fType)
1715 FieldDef field = new FieldDef(fAtts,name,fType);
1720 public void SetFieldOrder (ArrayList fields)
1722 this.fields = fields;
1726 /// Add a method to this class
1728 /// <param name="name">method name</param>
1729 /// <param name="retType">return type</param>
1730 /// <param name="pars">parameters</param>
1731 /// <returns>a descriptor for this new method</returns>
1732 public MethodDef AddMethod(string name, Type retType, Param[] pars)
1734 return AddMethod (name, new Param (ParamAttr.Default, "", retType), pars);
1737 public MethodDef AddMethod (string name, Param ret_param, Param [] pars)
1739 // Console.WriteLine("Adding method " + name + " to class " + this.name);
1740 MethodDef meth = new MethodDef(metaData,name, ret_param, pars);
1746 /// Add a method to this class
1748 /// <param name="mAtts">attributes for this method</param>
1749 /// <param name="iAtts">implementation attributes for this method</param>
1750 /// <param name="name">method name</param>
1751 /// <param name="retType">return type</param>
1752 /// <param name="pars">parameters</param>
1753 /// <returns>a descriptor for this new method</returns>
1754 public MethodDef AddMethod(MethAttr mAtts, ImplAttr iAtts, string name,
1755 Param ret_param, Param [] pars) {
1756 // Console.WriteLine("Adding method " + name + " to class " + this.name);
1757 MethodDef meth = new MethodDef (metaData, mAtts, iAtts, name, ret_param, pars);
1763 /// Add an event to this class
1765 /// <param name="name">event name</param>
1766 /// <param name="eType">event type</param>
1767 /// <returns>a descriptor for this new event</returns>
1768 public Event AddEvent(string name, Type eType)
1770 Event e = new Event(name,eType,this);
1771 if (events == null) events = new ArrayList();
1777 /// Add a property to this class
1779 /// <param name="name">property name</param>
1780 /// <param name="propType">property type</param>
1781 /// <returns>a descriptor for this new property</returns>
1782 public Property AddProperty(string name, Type retType, Type[] pars)
1784 Property p = new Property(name, retType, pars, this);
1785 if (properties == null) properties = new ArrayList();
1791 /// Add a nested class to this class
1793 /// <param name="attrSet">attributes for this nested class</param>
1794 /// <param name="nsName">nested name space name</param>
1795 /// <param name="name">nested class name</param>
1796 /// <returns>a descriptor for this new nested class</returns>
1797 public ClassDef AddNestedClass(TypeAttr attrSet, string nsName,
1799 ClassDef nClass = new ClassDef(attrSet,"",name,metaData);
1800 metaData.AddToTable(MDTable.TypeDef,nClass);
1801 metaData.AddToTable(MDTable.NestedClass,new MapElem(nClass,Row,MDTable.TypeDef));
1802 nClass.parentClass = this;
1806 public static bool IsValueType (Class type)
1808 return IsValueType (type.nameSpace, type.name);
1811 public static bool IsEnum (Class type)
1813 return IsEnum (type.nameSpace, type.name);
1816 public static bool IsValueType (string nsName, string name)
1818 return (nsName == "System" && name == "ValueType");
1821 public static bool IsEnum (string nsName, string name)
1823 return (nsName == "System" && name == "Enum");
1827 /// Add a nested class to this class
1829 /// <param name="attrSet">attributes for this nested class</param>
1830 /// <param name="nsName">nested name space name</param>
1831 /// <param name="name">nested class name</param>
1832 /// <param name="sType">super type of this nested class</param>
1833 /// <returns>a descriptor for this new nested class</returns>
1834 public ClassDef AddNestedClass(TypeAttr attrSet, string nsName,
1835 string name, Class sType) {
1836 ClassDef nClass = AddNestedClass (attrSet, nsName, name);
1837 nClass.SetSuper(sType);
1838 if (ClassDef.IsValueType (sType))
1839 nClass.MakeValueClass (ValueClass.ValueType);
1841 if (ClassDef.IsEnum (sType))
1842 nClass.MakeValueClass (ValueClass.Enum);
1844 if (ClassDef.IsValueType (sType) || ClassDef.IsEnum (sType))
1845 nClass.SetTypeIndex (PrimitiveType.ValueType.GetTypeIndex ());
1847 nClass.typeIndexChecked = true;
1852 /// Add layout information for this class. This class must have the
1853 /// sequential or explicit attribute.
1855 /// <param name="packSize">packing size (.pack)</param>
1856 /// <param name="classSize">class size (.size)</param>
1857 public void AddLayoutInfo (int packSize, int classSize)
1859 layout = new ClassLayout(packSize,classSize,this);
1863 /// Use a method as the implementation for another method (.override)
1865 /// <param name="decl">the method to be overridden</param>
1866 /// <param name="body">the implementation to be used</param>
1867 public void AddMethodOverride(Method decl, Method body)
1869 metaData.AddToTable(MDTable.MethodImpl,new MethodImpl(this,decl,body));
1873 /// Add security to this class NOT YET IMPLEMENTED
1875 /// <param name="permissionSet"></param>
1876 public void AddSecurity(byte[] permissionSet)
1878 throw(new NotYetImplementedException("Class security "));
1879 //flags |= HasSecurity;
1880 // securityActions = permissionSet;
1883 //public void AddLineInfo(int row, int col) { }
1885 internal void CheckTypeIndex()
1887 if (typeIndexChecked) return;
1888 if (superType is ClassDef)
1889 ((ClassDef)superType).CheckTypeIndex();
1890 typeIndex = superType.GetTypeIndex();
1891 typeIndexChecked = true;
1894 internal sealed override void BuildTables(MetaData md)
1897 if ((flags & (uint)TypeAttr.Interface) != 0) { superType = null; }
1898 // Console.WriteLine("Building tables for " + name);
1899 if (layout != null) md.AddToTable(MDTable.ClassLayout,layout);
1900 // Console.WriteLine("adding methods " + methods.Count);
1901 methodIx = md.TableIndex(MDTable.Method);
1902 for (int i=0; i < methods.Count; i++) {
1903 md.AddToTable(MDTable.Method,(MetaDataElement)methods[i]);
1904 ((MethodDef)methods[i]).BuildTables(md);
1906 // Console.WriteLine("adding fields");
1907 fieldIx = md.TableIndex(MDTable.Field);
1908 for (int i=0; i < fields.Count; i++) {
1909 md.AddToTable(MDTable.Field,(MetaDataElement)fields[i]);
1910 ((FieldDef)fields[i]).BuildTables(md);
1912 // Console.WriteLine("adding events and properties");
1913 if (events != null) {
1914 for (int i=0; i < events.Count; i++) {
1915 md.AddToTable(MDTable.Event,(Event)events[i]);
1916 ((Event)events[i]).BuildTables(md);
1918 md.AddToTable(MDTable.EventMap,
1919 new MapElem(this,((Event)events[0]).Row,MDTable.Event));
1921 if (properties != null) {
1922 for (int i=0; i < properties.Count; i++) {
1923 md.AddToTable(MDTable.Property,(Property)properties[i]);
1924 ((Property)properties[i]).BuildTables(md);
1926 md.AddToTable(MDTable.PropertyMap,new MapElem(this,
1927 ((Property)properties[0]).Row,MDTable.Property));
1929 // Console.WriteLine("End of building tables");
1933 internal sealed override uint Size(MetaData md)
1935 return 4 + 2 * md.StringsIndexSize() +
1936 md.CodedIndexSize(CIx.TypeDefOrRef) +
1937 md.TableIndexSize(MDTable.Field) +
1938 md.TableIndexSize(MDTable.Method);
1941 internal sealed override void Write(FileImage output)
1943 output.Write(flags);
1944 output.StringsIndex(nameIx);
1945 output.StringsIndex(nameSpaceIx);
1946 //if (superType != null)
1947 // Console.WriteLine("getting coded index for superType of " + name + " = " + superType.GetCodedIx(CIx.TypeDefOrRef));
1948 output.WriteCodedIndex(CIx.TypeDefOrRef,superType);
1949 output.WriteIndex(MDTable.Field,fieldIx);
1950 output.WriteIndex(MDTable.Method,methodIx);
1953 internal sealed override uint TypeDefOrRefToken()
1960 internal sealed override void TypeSig(MemoryStream sig)
1962 if (!typeIndexChecked) CheckTypeIndex();
1963 sig.WriteByte(GetTypeIndex());
1964 MetaData.CompressNum(TypeDefOrRefToken(),sig);
1967 internal sealed override uint GetCodedIx(CIx code)
1970 case (CIx.TypeDefOrRef) : return 0;
1971 case (CIx.HasCustomAttr) : return 3;
1972 case (CIx.HasDeclSecurity) : return 0;
1973 case (CIx.TypeOrMethodDef) : return 0;
1980 /**************************************************************************/
1982 /// Descriptor for a class/interface declared in another module of THIS
1983 /// assembly, or in another assembly.
1985 public class ClassRef : Class, IExternRef, IResolutionScope {
1987 protected IResolutionScope parent;
1988 protected MetaData metaData;
1990 internal ClassRef(string nsName, string name, MetaData md) : base(nsName, name, md)
1993 tabIx = MDTable.TypeRef;
1997 /// Add a method to this class
1999 /// <param name="name">method name</param>
2000 /// <param name="retType">return type</param>
2001 /// <param name="pars">parameter types</param>
2002 /// <returns>a descriptor for this method</returns>
2003 public MethodRef AddMethod(string name, Type retType, Type[] pars)
2005 return AddMethod (name, retType, pars, 0);
2009 /// Add a method to this class
2011 /// <param name="name">method name</param>
2012 /// <param name="retType">return type</param>
2013 /// <param name="pars">parameter types</param>
2014 /// <param name="gen_param_count">num of generic parameters</param>
2015 /// <returns>a descriptor for this method</returns>
2016 public MethodRef AddMethod (string name, Type retType, Type[] pars, int gen_param_count)
2018 MethodRef meth = new MethodRef (this, name, retType, pars, false, null, gen_param_count);
2019 metaData.AddToTable(MDTable.MemberRef,meth);
2024 /// Add a method to this class
2026 /// <param name="name">method name</param>
2027 /// <param name="retType">return type</param>
2028 /// <param name="pars">parameter types</param>
2029 /// <returns>a descriptor for this method</returns>
2030 public MethodRef AddVarArgMethod(string name, Type retType,
2031 Type[] pars, Type[] optPars)
2033 MethodRef meth = new MethodRef(this,name,retType,pars,true,optPars, 0);
2034 metaData.AddToTable(MDTable.MemberRef,meth);
2039 /// Add a field to this class
2041 /// <param name="name">field name</param>
2042 /// <param name="fType">field type</param>
2043 /// <returns>a descriptor for this field</returns>
2044 public FieldRef AddField(string name, Type fType)
2046 FieldRef field = new FieldRef(this,name,fType);
2047 metaData.AddToTable(MDTable.MemberRef,field);
2051 public ClassRef AddClass (string nsName, string name)
2053 ClassRef aClass = new ClassRef(nsName,name,metaData);
2054 metaData.AddToTable(MDTable.TypeRef,aClass);
2055 aClass.SetParent(this);
2059 public ClassRef AddValueClass (string nsName, string name)
2061 ClassRef aClass = AddClass (nsName, name);
2062 aClass.MakeValueClass (ValueClass.ValueType);
2066 internal void SetParent(IResolutionScope par)
2071 internal override string TypeName()
2073 if ((parent != null) && (parent is AssemblyRef))
2074 return (nameSpace + "." + name + ", " + ((AssemblyRef)parent).TypeName());
2076 return (nameSpace + name);
2079 internal sealed override uint Size(MetaData md)
2081 return md.CodedIndexSize(CIx.ResolutionScope) + 2 *
2082 md.StringsIndexSize();
2085 internal sealed override void Write(FileImage output)
2087 output.WriteCodedIndex(CIx.ResolutionScope,(MetaDataElement) parent);
2088 output.StringsIndex(nameIx);
2089 output.StringsIndex(nameSpaceIx);
2092 internal override sealed uint TypeDefOrRefToken()
2095 cIx = (cIx << 2) | 0x1;
2099 internal override void TypeSig(MemoryStream sig)
2101 sig.WriteByte(GetTypeIndex());
2102 MetaData.CompressNum(TypeDefOrRefToken(),sig);
2105 internal sealed override uint GetCodedIx(CIx code)
2108 case (CIx.TypeDefOrRef) : return 1;
2109 case (CIx.HasCustomAttr) : return 2;
2110 case (CIx.MemberRefParent) : return 1;
2111 case (CIx.ResolutionScope) : return 3;
2118 /**************************************************************************/
2119 public class ExternClassRef : ClassRef {
2121 ExternClass externClass;
2123 internal ExternClassRef(TypeAttr attrs, string nsName, string name,
2124 MetaDataElement declRef, MetaData md) : base(nsName,name,md)
2126 externClass = new ExternClass(attrs,nameSpaceIx,nameIx,declRef);
2127 metaData.AddToTable(MDTable.ExportedType,externClass);
2130 internal ExternClassRef(string name, MetaData md) : base(null,name,md)
2134 public ClassRef AddNestedClass(TypeAttr attrs, string name)
2136 ExternClassRef nestedClass = new ExternClassRef(name,metaData);
2137 externClass = new ExternClass(attrs,0,nameIx,this.externClass);
2138 metaData.AddToTable(MDTable.ExportedType,externClass);
2144 /**************************************************************************/
2146 /// Descriptor for a class defined in another module of THIS assembly
2147 /// and exported (.class extern)
2150 internal class ExternClass : Class {
2152 MetaDataElement parent;
2155 internal ExternClass(TypeAttr attr, uint nsIx, uint nIx,
2156 MetaDataElement paren) : base(nsIx,nIx)
2160 tabIx = MDTable.ExportedType;
2163 internal sealed override uint Size(MetaData md)
2165 return 8 + 2* md.StringsIndexSize() + md.CodedIndexSize(CIx.Implementation);
2168 internal sealed override void Write(FileImage output)
2170 output.Write(flags);
2172 output.StringsIndex(nameIx);
2173 output.StringsIndex(nameSpaceIx);
2174 output.WriteCodedIndex(CIx.Implementation,parent);
2177 internal sealed override uint GetCodedIx(CIx code)
2180 case (CIx.HasCustomAttr) : return 17;
2181 case (CIx.Implementation) : return 2;
2188 public class GenParam : Class {
2191 private string param_name;
2192 private uint sigIx = 0;
2194 public GenParam (int index, string name, GenParamType ptype) : base ((byte) ptype)
2197 this.param_name = name;
2198 tabIx = MDTable.TypeSpec;
2202 get { return index; }
2203 set { index = value; }
2206 public string Name {
2207 get { return param_name; }
2208 set { param_name = value; }
2211 public GenParamType Type {
2212 get { return (GenParamType) GetTypeIndex (); }
2215 internal sealed override void BuildTables (MetaData md)
2219 MemoryStream str = new MemoryStream ();
2221 sigIx = md.AddToBlobHeap (str.ToArray ());
2226 internal sealed override void TypeSig(MemoryStream str)
2229 throw new PEFileException (String.Format ("Unresolved {0} - {1}", (GenParamType) GetTypeIndex (), param_name));
2230 str.WriteByte(typeIndex);
2231 MetaData.CompressNum ((uint) index, str);
2234 internal override uint Size(MetaData md)
2236 return md.BlobIndexSize();
2239 internal sealed override void Write (FileImage output)
2241 output.BlobIndex (sigIx);
2244 internal sealed override uint GetCodedIx(CIx code)
2247 case (CIx.TypeDefOrRef) : return 2;
2248 case (CIx.HasCustomAttr) : return 13;
2249 case (CIx.MemberRefParent) : return 4;
2255 public class GenericTypeInst : Class {
2257 private Type gen_type;
2258 private Type[] gen_param;
2259 bool inTable = false;
2262 public GenericTypeInst (Type gen_type, Type[] gen_param)
2263 : base ((byte) PrimitiveType.GenericInst.GetTypeIndex ())
2265 this.gen_type = gen_type;
2266 this.gen_param = gen_param;
2267 tabIx = MDTable.TypeSpec;
2270 internal override MetaDataElement GetTypeSpec (MetaData md)
2273 md.AddToTable (MDTable.TypeSpec, this);
2280 internal sealed override void TypeSig(MemoryStream str)
2282 str.WriteByte(typeIndex);
2283 gen_type.TypeSig (str);
2284 MetaData.CompressNum ((uint) gen_param.Length, str);
2285 foreach (Type param in gen_param)
2286 param.TypeSig (str);
2289 internal sealed override void BuildTables (MetaData md)
2293 MemoryStream str = new MemoryStream ();
2295 sigIx = md.AddToBlobHeap (str.ToArray ());
2300 internal sealed override uint Size (MetaData md)
2302 return md.BlobIndexSize ();
2305 internal sealed override void Write (FileImage output)
2307 output.BlobIndex (sigIx);
2310 internal sealed override uint GetCodedIx (CIx code)
2313 case (CIx.TypeDefOrRef): return 2;
2314 case (CIx.MemberRefParent): return 4;
2315 case (CIx.HasCustomAttr): return 13;
2321 public class GenericMethodSig {
2323 private Type[] gen_param;
2325 private uint sigIx = 0;
2327 public GenericMethodSig (Type[] gen_param)
2329 this.gen_param = gen_param;
2333 internal void TypeSig (MemoryStream str)
2335 str.WriteByte (0x0A); /* GENERIC_INST */
2336 MetaData.CompressNum ((uint) gen_param.Length, str);
2337 foreach (Type param in gen_param)
2338 param.TypeSig (str);
2341 internal uint GetSigIx (MetaData md)
2346 MemoryStream sig = new MemoryStream();
2348 sigIx = md.AddToBlobHeap (sig.ToArray());
2354 public class Sentinel : Type {
2356 public Sentinel () : base (0x41) { }
2358 internal sealed override void TypeSig(MemoryStream str)
2360 str.WriteByte(typeIndex);
2364 /**************************************************************************/
2366 /// Descriptor for a FunctionPointer type
2369 public class MethPtrType : Type {
2381 /// Create a new function pointer type
2383 /// <param name="meth">the function to be referenced</param>
2384 public MethPtrType (CallConv callconv, Type retType, Type[] pars,
2385 bool varArgMeth, Type[] optPars) : base(0x1B)
2387 this.retType = retType;
2388 callConv = callconv;
2390 this.varArgMeth = varArgMeth;
2391 if (parList != null) numPars = (uint)parList.Length;
2393 optParList = optPars;
2394 if (optParList != null) numOptPars = (uint)optParList.Length;
2395 callConv |= CallConv.Vararg;
2397 tabIx = MDTable.TypeSpec;
2400 internal sealed override void TypeSig(MemoryStream sig)
2402 sig.WriteByte(typeIndex);
2403 // Bootlegged from method ref
2404 sig.WriteByte((byte)callConv);
2405 MetaData.CompressNum (numPars + numOptPars, sig);
2406 retType.TypeSig (sig);
2407 for (int i=0; i < numPars; i++) {
2408 parList[i].TypeSig (sig);
2411 sig.WriteByte (0x41); // Write the sentinel
2412 for (int i=0; i < numOptPars; i++) {
2413 optParList[i].TypeSig (sig);
2418 internal sealed override void BuildTables(MetaData md)
2421 MemoryStream sig = new MemoryStream();
2423 sigIx = md.AddToBlobHeap(sig.ToArray());
2427 internal sealed override uint Size(MetaData md)
2429 return md.BlobIndexSize();
2432 internal sealed override void Write(FileImage output)
2434 output.BlobIndex(sigIx);
2437 internal sealed override uint GetCodedIx(CIx code) { return 0x1B; }
2442 /* Classes for Arrays */
2445 /// The IL Array type
2447 public abstract class Array : Type {
2449 protected Type elemType;
2450 protected MetaData metaData;
2451 protected string cnameSpace, cname;
2453 internal Array(Type eType, byte TypeId) : base(TypeId)
2456 tabIx = MDTable.TypeSpec;
2461 /// Single dimensional array with zero lower bound
2463 public class ZeroBasedArray : Array {
2466 /// Create a new array - elementType[]
2468 /// <param name="elementType">the type of the array elements</param>
2469 public ZeroBasedArray(Type elementType) : base (elementType, PrimitiveType.SZArray.GetTypeIndex ()) { }
2471 internal sealed override void TypeSig(MemoryStream str)
2473 str.WriteByte(typeIndex);
2474 elemType.TypeSig(str);
2480 /// Multi dimensional array with explicit bounds
2482 public class BoundArray : Array {
2488 /// Create a new multi dimensional array type
2489 /// eg. elemType[1..5,3..10,5,,] would be
2490 /// new BoundArray(elemType,5,[1,3,0],[5,10,4])
2492 /// <param name="elementType">the type of the elements</param>
2493 /// <param name="dimensions">the number of dimensions</param>
2494 /// <param name="loBounds">lower bounds of dimensions</param>
2495 /// <param name="sizes">sizes for the dimensions</param>
2496 public BoundArray(Type elementType, uint dimensions, int[] loBounds,
2497 int[] sizes) : base (elementType,0x14)
2499 numDims = dimensions;
2500 lowerBounds = loBounds;
2505 /// Create a new multi dimensional array type
2506 /// eg. elemType[5,10,20] would be new BoundArray(elemType,3,[5,10,20])
2508 /// <param name="elementType">the type of the elements</param>
2509 /// <param name="dimensions">the number of dimensions</param>
2510 /// <param name="size">the sizes of the dimensions</param>
2511 public BoundArray(Type elementType, uint dimensions, int[] size)
2512 : base (elementType,0x14)
2514 numDims = dimensions;
2519 /// Create a new multi dimensional array type
2520 /// eg. elemType[,,] would be new BoundArray(elemType,3)
2522 /// <param name="elementType">the type of the elements</param>
2523 /// <param name="dimensions">the number of dimensions</param>
2524 public BoundArray(Type elementType, uint dimensions)
2525 : base (elementType,0x14)
2527 numDims = dimensions;
2530 internal sealed override void TypeSig(MemoryStream str)
2532 str.WriteByte(typeIndex);
2533 elemType.TypeSig(str);
2534 MetaData.CompressNum(numDims,str);
2535 if ((sizes != null) && (sizes.Length > 0)) {
2537 MetaData.CompressNum((uint)sizes.Length,str);
2538 for (int i=0; i < sizes.Length; i++) {
2539 MetaData.CompressNum((uint)sizes[i],str);
2541 } else str.WriteByte(0);
2542 if ((lowerBounds != null) && (lowerBounds.Length > 0)) {
2543 MetaData.CompressNum((uint)lowerBounds.Length,str);
2544 for (int i=0; i < lowerBounds.Length; i++) {
2545 CompressSignedNum (lowerBounds[i],str);
2547 } else str.WriteByte(0);
2549 private void CompressSignedNum (int val, MemoryStream str)
2551 uint uval = (uint) val;
2558 /* Map the signed number to an unsigned number in two ways.
2560 fval: left-rotated 2's complement representation
2561 sval: map the signed number to unsigned as follows: 0 -> 0, -1 -> 1, 1 -> 2, -2 -> 3, 2 -> 4, ....
2562 the mapping is: x -> 2*|x| - signbit(x)
2564 uint fval = (uval << 1) | sign;
2565 int sval = (val << 1) - sign;
2567 /* An overly clever transformation:
2569 a. sval is used to determine the number of bytes in the compressed representation.
2570 b. fval is truncated to the appropriate number of bits and output using the
2571 normal unsigned-int compressor.
2573 However, or certain values, the truncated fval doesn't carry enough information to round trip.
2575 (fval & 0x3FFF) <= 0x7F => compressor emits 1 byte, not 2 => there is aliasing of values
2577 So, we use full 4 bytes to encode such values.
2579 LAMESPEC: The Microsoft implementation doesn't appear to handle this subtle case.
2580 e.g., it ends up encoding -8192 as the byte 0x01, which decodes to -64
2583 MetaData.CompressNum (fval & 0x7F, str);
2584 else if (sval <= 0x3FFF && (fval & 0x3FFF) > 0x7F)
2585 MetaData.CompressNum (fval & 0x3FFF, str);
2586 else if (sval <= 0x1FFFFFFF && (fval & 0x1FFFFFFF) > 0x3FFF)
2587 MetaData.CompressNum (fval & 0x1FFFFFFF, str);
2589 /* FIXME: number cannot be represented. Report a warning. */
2590 // throw new Exception ("cannot represent signed value" + -val);
2591 MetaData.CompressNum (fval, str);
2598 /* Empty interface for grouping TypeRef's possible ResolutionScope
2599 namely : Module, ModuleRef, AssemblyRef and TypeRef */
2600 public interface IResolutionScope {
2603 /**************************************************************************/
2605 /// Base class for scopes (extended by Module, ModuleRef, Assembly, AssemblyRef)
2607 public abstract class ResolutionScope : MetaDataElement, IResolutionScope {
2609 protected uint nameIx = 0;
2610 protected MetaData metaData;
2611 protected string name;
2613 internal ResolutionScope(string name, MetaData md)
2617 nameIx = md.AddToStringsHeap(name);
2620 internal string GetName() { return name; }
2624 /**************************************************************************/
2626 /// Descriptor for THIS assembly (.assembly)
2628 public class Assembly : ResolutionScope {
2630 ushort majorVer, minorVer, buildNo, revisionNo;
2633 uint keyIx = 0, cultIx = 0;
2634 bool hasPublicKey = false;
2636 internal Assembly(string name, MetaData md) : base(name,md)
2638 tabIx = MDTable.Assembly;
2642 /// Add details about THIS assembly
2644 /// <param name="majVer">Major Version</param>
2645 /// <param name="minVer">Minor Version</param>
2646 /// <param name="bldNo">Build Number</param>
2647 /// <param name="revNo">Revision Number</param>
2648 /// <param name="key">Hash Key</param>
2649 /// <param name="hash">Hash Algorithm</param>
2650 /// <param name="cult">Culture</param>
2651 public void AddAssemblyInfo(int majVer, int minVer, int bldNo, int revNo,
2652 byte[] key, uint hash, string cult)
2654 majorVer = (ushort)majVer;
2655 minorVer = (ushort)minVer;
2656 buildNo = (ushort)bldNo;
2657 revisionNo = (ushort)revNo;
2659 hasPublicKey = (key != null);
2660 keyIx = metaData.AddToBlobHeap(key);
2661 cultIx = metaData.AddToStringsHeap(cult);
2665 /// Add an attribute to THIS assembly
2667 /// <param name="aa">assembly attribute</param>
2668 public void AddAssemblyAttr(AssemAttr aa)
2673 internal sealed override uint Size(MetaData md)
2675 return 16 + md.BlobIndexSize() + 2 * md.StringsIndexSize();
2678 internal sealed override void Write(FileImage output)
2680 // Console.WriteLine("Writing assembly element with nameIx of " + nameIx + " at file offset " + output.Seek(0,SeekOrigin.Current));
2681 output.Write((uint)hashAlgId);
2682 output.Write(majorVer);
2683 output.Write(minorVer);
2684 output.Write(buildNo);
2685 output.Write(revisionNo);
2686 output.Write(flags);
2687 output.BlobIndex(keyIx);
2688 output.StringsIndex(nameIx);
2689 output.StringsIndex(cultIx);
2692 internal sealed override uint GetCodedIx(CIx code)
2695 case (CIx.HasCustomAttr) : return 14;
2696 case (CIx.HasDeclSecurity) : return 2;
2701 internal bool HasPublicKey {
2702 get { return hasPublicKey; }
2706 /**************************************************************************/
2708 /// Descriptor for THIS module
2710 public class Module : ResolutionScope, IExternRef {
2715 internal Module(string name, MetaData md) : base(name,md)
2717 mvid = Guid.NewGuid();
2718 mvidIx = md.AddToGUIDHeap(mvid);
2719 tabIx = MDTable.Module;
2723 get { return mvid; }
2726 public ClassRef AddClass(string nsName, string name)
2728 ClassRef aClass = new ClassRef (nsName, name, metaData);
2729 metaData.AddToTable (MDTable.TypeRef, aClass);
2730 aClass.SetParent (this);
2734 public ClassRef AddValueClass(string nsName, string name)
2736 ClassRef aClass = AddClass (nsName, name);
2737 aClass.MakeValueClass (ValueClass.ValueType);
2741 internal sealed override uint Size(MetaData md)
2743 return 2 + md.StringsIndexSize() + 3 * md.GUIDIndexSize();
2746 internal sealed override void Write(FileImage output)
2748 output.Write((short)0);
2749 output.StringsIndex(nameIx);
2750 output.GUIDIndex(mvidIx);
2751 output.GUIDIndex(0);
2752 output.GUIDIndex(0);
2755 internal sealed override uint GetCodedIx(CIx code)
2758 case (CIx.HasCustomAttr) : return 7;
2759 case (CIx.ResolutionScope) : return 0;
2764 /**************************************************************************/
2766 /// Descriptor for another module in THIS assembly
2768 public class ModuleRef : ResolutionScope, IExternRef {
2770 internal ModuleRef(MetaData md, string name) : base(name,md)
2772 tabIx = MDTable.ModuleRef;
2776 /// Add a class to this external module. This is a class declared in
2777 /// another module of THIS assembly.
2779 /// <param name="nsName">name space name</param>
2780 /// <param name="name">class name</param>
2781 /// <returns>a descriptor for this class in another module</returns>
2782 public ClassRef AddClass(string nsName, string name)
2784 ClassRef aClass = new ClassRef(nsName,name,metaData);
2785 metaData.AddToTable(MDTable.TypeRef,aClass);
2786 aClass.SetParent(this);
2791 /// Make a file descriptor to correspond to this module. The file
2792 /// descriptor will have the same name as the module descriptor
2794 /// <param name="hashBytes">the hash of the file</param>
2795 /// <param name="hasMetaData">the file contains metadata</param>
2796 /// <param name="entryPoint">the program entry point is in this file</param>
2797 /// <returns>a descriptor for the file which contains this module</returns>
2798 public FileRef MakeFile(byte[] hashBytes, bool hasMetaData, bool entryPoint)
2800 FileRef file = new FileRef(nameIx,hashBytes,hasMetaData,entryPoint,metaData);
2801 metaData.AddToTable(MDTable.File,file);
2806 /// Add a value class to this module. This is a class declared in
2807 /// another module of THIS assembly.
2809 /// <param name="nsName">name space name</param>
2810 /// <param name="name">class name</param>
2811 /// <returns></returns>
2812 public ClassRef AddValueClass(string nsName, string name)
2814 ClassRef aClass = new ClassRef(nsName,name,metaData);
2815 metaData.AddToTable(MDTable.TypeRef,aClass);
2816 aClass.SetParent(this);
2817 aClass.MakeValueClass(ValueClass.ValueType);
2822 /// Add a class which is declared public in this external module of
2823 /// THIS assembly. This class will be exported from this assembly.
2824 /// The ilasm syntax for this is .extern class
2826 /// <param name="attrSet">attributes of the class to be exported</param>
2827 /// <param name="nsName">name space name</param>
2828 /// <param name="name">external class name</param>
2829 /// <param name="declFile">the file where the class is declared</param>
2830 /// <param name="isValueClass">is this class a value type?</param>
2831 /// <returns>a descriptor for this external class</returns>
2832 public ExternClassRef AddExternClass(TypeAttr attrSet, string nsName,
2833 string name, FileRef declFile,
2834 bool isValueClass) {
2835 ExternClassRef cRef = new ExternClassRef(attrSet,nsName,name,declFile,metaData);
2836 metaData.AddToTable(MDTable.TypeRef,cRef);
2837 cRef.SetParent(this);
2838 if (isValueClass) cRef.MakeValueClass(ValueClass.ValueType);
2843 /// Add a "global" method in another module
2845 /// <param name="name">method name</param>
2846 /// <param name="retType">return type</param>
2847 /// <param name="pars">method parameter types</param>
2848 /// <returns>a descriptor for this method in anther module</returns>
2849 public MethodRef AddMethod(string name, Type retType, Type[] pars)
2851 MethodRef meth = new MethodRef(this,name,retType,pars,false,null, 0);
2852 metaData.AddToTable(MDTable.MemberRef,meth);
2857 /// Add a vararg method to this class
2859 /// <param name="name">method name</param>
2860 /// <param name="retType">return type</param>
2861 /// <param name="pars">parameter types</param>
2862 /// <param name="optPars">optional param types for this vararg method</param>
2863 /// <returns>a descriptor for this method</returns>
2864 public MethodRef AddVarArgMethod(string name, Type retType,
2865 Type[] pars, Type[] optPars) {
2866 MethodRef meth = new MethodRef(this,name,retType,pars,true,optPars, 0);
2867 metaData.AddToTable(MDTable.MemberRef,meth);
2872 /// Add a field in another module
2874 /// <param name="name">field name</param>
2875 /// <param name="fType">field type</param>
2876 /// <returns>a descriptor for this field in another module</returns>
2877 public FieldRef AddField(string name, Type fType)
2879 FieldRef field = new FieldRef(this,name,fType);
2880 metaData.AddToTable(MDTable.MemberRef,field);
2884 internal sealed override uint Size(MetaData md)
2886 return md.StringsIndexSize();
2889 internal sealed override void Write(FileImage output)
2891 output.StringsIndex(nameIx);
2894 internal sealed override uint GetCodedIx(CIx code)
2897 case (CIx.HasCustomAttr) : return 12;
2898 case (CIx.MemberRefParent) : return 2;
2899 case (CIx.ResolutionScope) : return 1;
2906 #region Classes for Constants
2908 /// Descriptor for a constant value
2910 public abstract class Constant {
2911 protected uint size = 0;
2912 protected Type type;
2913 protected uint blobIndex;
2914 protected bool addedToBlobHeap = false;
2916 internal Constant() { }
2918 internal virtual uint GetBlobIndex(MetaData md) { return 0; }
2920 internal uint GetSize() { return size; }
2922 internal byte GetTypeIndex() { return type.GetTypeIndex(); }
2924 internal virtual void Write(BinaryWriter bw) { }
2928 /// Descriptor for a constant value
2930 public abstract class DataConstant : Constant {
2931 private uint dataOffset = 0;
2933 internal DataConstant() { }
2935 public uint DataOffset {
2936 get { return dataOffset; }
2937 set { dataOffset = value; }
2943 /// Boolean constant
2945 public class BoolConst : Constant {
2949 /// Create a new boolean constant with the value "val"
2951 /// <param name="val">value of this boolean constant</param>
2952 public BoolConst(bool val)
2956 type = PrimitiveType.Boolean;
2959 internal sealed override uint GetBlobIndex(MetaData md)
2961 if (!addedToBlobHeap) {
2962 if (val) blobIndex = md.AddToBlobHeap((sbyte)1);
2963 else blobIndex = md.AddToBlobHeap((sbyte)0);
2964 addedToBlobHeap = true;
2969 internal sealed override void Write(BinaryWriter bw)
2971 if (val) bw.Write((sbyte)1);
2972 else bw.Write((sbyte)0);
2977 public class ByteArrConst : DataConstant {
2978 internal byte[] val;
2980 public ByteArrConst(byte[] val)
2982 type = PrimitiveType.String;
2984 size = (uint)val.Length;
2988 get { return type; }
2989 set { type = value; }
2992 internal sealed override uint GetBlobIndex(MetaData md)
2994 if (!addedToBlobHeap) {
2995 blobIndex = md.AddToBlobHeap(val);
2996 addedToBlobHeap = true;
3001 internal sealed override void Write(BinaryWriter bw)
3008 public class CharConst : Constant {
3011 public CharConst(char val)
3015 type = PrimitiveType.Char;
3018 internal sealed override uint GetBlobIndex(MetaData md)
3020 if (!addedToBlobHeap) {
3021 blobIndex = md.AddToBlobHeap(val);
3022 addedToBlobHeap = true;
3027 internal sealed override void Write(BinaryWriter bw)
3034 public class FloatConst : DataConstant {
3037 public FloatConst(float val)
3041 type = PrimitiveType.Float32;
3044 internal sealed override uint GetBlobIndex(MetaData md)
3046 if (!addedToBlobHeap) {
3047 blobIndex = md.AddToBlobHeap(val);
3048 addedToBlobHeap = true;
3053 internal sealed override void Write(BinaryWriter bw)
3060 public class DoubleConst : DataConstant {
3063 public DoubleConst(double val)
3067 type = PrimitiveType.Float64;
3070 internal sealed override uint GetBlobIndex(MetaData md)
3072 if (!addedToBlobHeap) {
3073 blobIndex = md.AddToBlobHeap(val);
3074 addedToBlobHeap = true;
3079 internal sealed override void Write(BinaryWriter bw)
3086 public class IntConst : DataConstant {
3089 public IntConst(sbyte val)
3093 type = PrimitiveType.Int8;
3096 public IntConst(short val)
3100 type = PrimitiveType.Int16;
3103 public IntConst(int val)
3107 type = PrimitiveType.Int32;
3110 public IntConst(long val)
3114 type = PrimitiveType.Int64;
3117 internal sealed override uint GetBlobIndex(MetaData md)
3119 if (!addedToBlobHeap) {
3121 case (1) : blobIndex = md.AddToBlobHeap((sbyte)val); break;
3122 case (2) : blobIndex = md.AddToBlobHeap((short)val); break;
3123 case (4) : blobIndex = md.AddToBlobHeap((int)val); break;
3124 default : blobIndex = md.AddToBlobHeap(val); break;
3126 addedToBlobHeap = true;
3131 internal sealed override void Write(BinaryWriter bw)
3134 case (1) : bw.Write((sbyte)val); break;
3135 case (2) : bw.Write((short)val); break;
3136 case (4) : bw.Write((int)val); break;
3137 default : bw.Write(val); break;
3143 public class UIntConst : Constant {
3146 public UIntConst(byte val)
3150 type = PrimitiveType.UInt8;
3152 public UIntConst(ushort val)
3156 type = PrimitiveType.UInt16;
3158 public UIntConst(uint val)
3162 type = PrimitiveType.UInt32;
3164 public UIntConst(ulong val)
3168 type = PrimitiveType.UInt64;
3171 internal sealed override uint GetBlobIndex(MetaData md)
3173 if (!addedToBlobHeap) {
3175 case (1) : blobIndex = md.AddToBlobHeap((byte)val); break;
3176 case (2) : blobIndex = md.AddToBlobHeap((ushort)val); break;
3177 case (4) : blobIndex = md.AddToBlobHeap((uint)val); break;
3178 default : blobIndex = md.AddToBlobHeap(val); break;
3180 addedToBlobHeap = true;
3185 internal sealed override void Write(BinaryWriter bw)
3188 case (1) : bw.Write((byte)val); break;
3189 case (2) : bw.Write((ushort)val); break;
3190 case (4) : bw.Write((uint)val); break;
3191 default : bw.Write(val); break;
3197 public class StringConst : DataConstant {
3198 internal string val;
3200 public StringConst(string val)
3203 size = (uint)val.Length; // need to add null ??
3204 type = PrimitiveType.String;
3207 internal sealed override uint GetBlobIndex(MetaData md)
3209 if (!addedToBlobHeap) {
3210 byte [] b = Encoding.Unicode.GetBytes (val);
3211 blobIndex = md.AddToBlobHeap(b);
3212 addedToBlobHeap = true;
3217 internal sealed override void Write(BinaryWriter bw)
3224 public class NullConst : Constant {
3229 type = PrimitiveType.Class;
3232 internal sealed override uint GetBlobIndex(MetaData md)
3234 if (!addedToBlobHeap) {
3235 blobIndex = md.AddToBlobHeap((int)0);
3236 addedToBlobHeap = true;
3241 internal sealed override void Write(BinaryWriter bw)
3248 public class AddressConstant : DataConstant {
3251 public AddressConstant(DataConstant dConst)
3255 type = PrimitiveType.TypedRef;
3258 internal sealed override void Write(BinaryWriter bw)
3260 ((FileImage)bw).WriteDataRVA(data.DataOffset);
3265 public class RepeatedConstant : DataConstant {
3269 public RepeatedConstant(DataConstant dConst, int repeatCount)
3272 repCount = (uint)repeatCount;
3273 int[] sizes = new int[1];
3274 sizes[0] = repeatCount;
3275 type = new BoundArray(type,1,sizes);
3276 size = data.GetSize() * repCount;
3279 internal sealed override void Write(BinaryWriter bw)
3281 for (int i=0; i < repCount; i++) {
3288 public class ArrayConstant : DataConstant {
3289 DataConstant[] dataVals;
3291 public ArrayConstant(DataConstant[] dVals)
3294 for (int i=0; i < dataVals.Length; i++) {
3295 size += dataVals[i].GetSize();
3299 internal sealed override void Write(BinaryWriter bw)
3301 for (int i=0; i < dataVals.Length; i++) {
3302 dataVals[i].Write(bw);
3308 public class ClassType : Constant {
3312 public ClassType(string className)
3315 type = PrimitiveType.ClassType;
3318 public ClassType(Class classDesc)
3321 type = PrimitiveType.ClassType;
3324 internal override void Write(BinaryWriter bw)
3326 if (name == null) name = desc.TypeName();
3334 /**************************************************************************/
3336 /// Descriptor for a custom modifier of a type (modopt or modreq)
3339 public class CustomModifiedType : Type {
3343 PrimitiveTypeRef cmodPrimType;
3346 /// Create a new custom modifier for a type
3348 /// <param name="type">the type to be modified</param>
3349 /// <param name="cmod">the modifier</param>
3350 /// <param name="cmodType">the type reference to be associated with the type</param>
3351 public CustomModifiedType(Type type, CustomModifier cmod, Class cmodType)
3355 this.cmodType = cmodType;
3358 public CustomModifiedType(Type type, CustomModifier cmod, PrimitiveTypeRef cmodType)
3362 this.cmodPrimType = cmodType;
3365 internal sealed override void TypeSig(MemoryStream str)
3367 str.WriteByte(typeIndex);
3369 if (cmodType != null) {
3370 MetaData.CompressNum(cmodType.TypeDefOrRefToken(),str);
3372 MetaData.CompressNum(cmodPrimType.TypeDefOrRefToken(),str);
3380 /**************************************************************************/
3382 /// Base class for Event and Property descriptors
3385 public class Feature : MetaDataElement {
3387 internal enum MethodType : ushort { Setter = 0x01, Getter, Other = 0x04, AddOn = 0x08,
3388 RemoveOn = 0x10, Fire = 0x20 }
3390 private static readonly int INITSIZE = 5;
3391 private static readonly ushort specialName = 0x200;
3392 private static readonly ushort rtSpecialName = 0x400;
3394 protected ClassDef parent;
3395 protected ushort flags = 0;
3396 protected string name;
3397 protected int tide = 0;
3398 protected uint nameIx;
3399 protected MethodSemantics[] methods = new MethodSemantics[INITSIZE];
3401 internal Feature(string name, ClassDef par)
3407 internal void AddMethod(MethodDef meth, MethodType mType)
3409 if (tide >= methods.Length) {
3410 int len = methods.Length;
3411 MethodSemantics[] mTmp = methods;
3412 methods = new MethodSemantics[len * 2];
3413 for (int i=0; i < len; i++) {
3414 methods[i] = mTmp[i];
3417 methods[tide++] = new MethodSemantics(mType,meth,this);
3421 /// Set the specialName attribute for this Event or Property
3423 public void SetSpecialName()
3425 flags |= specialName;
3429 /// Set the RTSpecialName attribute for this Event or Property
3431 public void SetRTSpecialName()
3433 flags |= rtSpecialName;
3438 /**************************************************************************/
3440 /// Descriptor for an event
3442 public class Event : Feature {
3446 internal Event(string name, Type eType, ClassDef parent)
3447 : base(name, parent)
3450 tabIx = MDTable.Event;
3454 /// Add the addon method to this event
3456 /// <param name="addon">the addon method</param>
3457 public void AddAddon(MethodDef addon)
3459 AddMethod(addon,MethodType.AddOn);
3463 /// Add the removeon method to this event
3465 /// <param name="removeOn">the removeon method</param>
3466 public void AddRemoveOn(MethodDef removeOn)
3468 AddMethod(removeOn,MethodType.RemoveOn);
3472 /// Add the fire method to this event
3474 /// <param name="fire">the fire method</param>
3475 public void AddFire(MethodDef fire)
3477 AddMethod(fire,MethodType.Fire);
3481 /// Add another method to this event
3483 /// <param name="other">the method to be added</param>
3484 public void AddOther(MethodDef other)
3486 AddMethod(other,MethodType.Other);
3489 internal sealed override void BuildTables(MetaData md)
3492 nameIx = md.AddToStringsHeap(name);
3493 for (int i=0; i < tide; i++) {
3494 md.AddToTable(MDTable.MethodSemantics,methods[i]);
3499 internal sealed override uint Size(MetaData md)
3501 return 2 + md.StringsIndexSize() + md.CodedIndexSize(CIx.TypeDefOrRef);
3504 internal sealed override void Write(FileImage output)
3506 output.Write(flags);
3507 output.StringsIndex(nameIx);
3508 output.WriteCodedIndex(CIx.TypeDefOrRef,eventType);
3511 internal sealed override uint GetCodedIx(CIx code)
3514 case (CIx.HasCustomAttr) : return 10;
3515 case (CIx.HasSemantics) : return 0;
3522 /**************************************************************************/
3524 /// Descriptor for the Property of a class
3526 public class Property : Feature {
3528 private static readonly byte PropertyTag = 0x8;
3529 private bool instance;
3530 MethodDef getterMeth;
3531 ConstantElem constVal;
3532 uint typeBlobIx = 0;
3537 internal Property(string name, Type retType, Type[] pars, ClassDef parent) : base(name, parent)
3539 returnType = retType;
3541 if (pars != null) numPars = (uint)pars.Length;
3542 tabIx = MDTable.Property;
3546 /// Add a set method to this property
3548 /// <param name="setter">the set method</param>
3549 public void AddSetter(MethodDef setter)
3551 AddMethod(setter,MethodType.Setter);
3555 /// Add a get method to this property
3557 /// <param name="getter">the get method</param>
3558 public void AddGetter(MethodDef getter)
3560 AddMethod(getter,MethodType.Getter);
3561 getterMeth = getter;
3565 /// Add another method to this property
3567 /// <param name="other">the method</param>
3568 public void AddOther(MethodDef other)
3570 AddMethod(other,MethodType.Other);
3574 /// Add an initial value for this property
3576 /// <param name="constVal">the initial value for this property</param>
3577 public void AddInitValue(Constant constVal)
3579 this.constVal = new ConstantElem(this,constVal);
3582 public void SetInstance (bool isInstance)
3584 this.instance = isInstance;
3587 internal sealed override void BuildTables(MetaData md)
3590 nameIx = md.AddToStringsHeap(name);
3591 MemoryStream sig = new MemoryStream();
3592 byte tag = PropertyTag;
3596 MetaData.CompressNum(numPars,sig);
3597 returnType.TypeSig(sig);
3598 for (int i=0; i < numPars; i++) {
3599 parList[i].TypeSig(sig);
3601 typeBlobIx = md.AddToBlobHeap(sig.ToArray());
3602 for (int i=0; i < tide; i++) {
3603 md.AddToTable(MDTable.MethodSemantics,methods[i]);
3605 if (constVal != null) {
3606 md.AddToTable(MDTable.Constant,constVal);
3607 constVal.BuildTables(md);
3612 internal sealed override uint Size(MetaData md)
3614 return 2 + md.StringsIndexSize() + md.BlobIndexSize();
3617 internal sealed override void Write(FileImage output)
3619 output.Write(flags);
3620 output.StringsIndex(nameIx);
3621 output.BlobIndex(typeBlobIx);
3624 internal sealed override uint GetCodedIx(CIx code)
3627 case (CIx.HasCustomAttr) : return 9;
3628 case (CIx.HasConst) : return 2;
3629 case (CIx.HasSemantics) : return 1;
3636 /**************************************************************************/
3638 /// Base class for field/methods (member of a class)
3640 public abstract class Member : MetaDataElement {
3642 protected string name;
3643 protected uint nameIx = 0, sigIx = 0;
3645 internal Member(string memName)
3648 tabIx = MDTable.MemberRef;
3653 /*****************************************************************************/
3655 /// Descriptor for a field of a class
3658 public abstract class Field : Member {
3660 protected static readonly byte FieldSig = 0x6;
3662 protected Type type;
3664 internal Field(string pfName, Type pfType) : base(pfName)
3670 /**************************************************************************/
3672 /// Descriptor for a field defined in a class of THIS assembly/module
3674 public class FieldDef : Field {
3676 //private static readonly uint PInvokeImpl = 0x2000;
3677 private static readonly ushort HasFieldRVA = 0x100;
3678 private static readonly ushort HasDefault = 0x8000;
3681 ConstantElem constVal;
3683 FieldMarshal marshalInfo;
3686 internal FieldDef(string name, Type fType) : base(name,fType)
3688 tabIx = MDTable.Field;
3691 internal FieldDef(FieldAttr attrSet, string name, Type fType) : base(name, fType)
3693 flags = (ushort)attrSet;
3694 tabIx = MDTable.Field;
3698 /// Add an attribute(s) to this field
3700 /// <param name="fa">the attribute(s) to be added</param>
3701 public void AddFieldAttr(FieldAttr fa)
3703 flags |= (ushort)fa;
3707 /// Add a value for this field
3709 /// <param name="val">the value for the field</param>
3710 public void AddValue(Constant val)
3712 constVal = new ConstantElem(this,val);
3713 flags |= HasDefault;
3717 /// Add an initial value for this field (at dataLabel) (.data)
3719 /// <param name="val">the value for the field</param>
3720 /// <param name="repeatVal">the number of repetitions of this value</param>
3721 public void AddDataValue(DataConstant val)
3723 flags |= HasFieldRVA;
3724 rva = new FieldRVA(this,val);
3728 /// Set the offset of the field. Used for sequential or explicit classes.
3731 /// <param name="offs">field offset</param>
3732 public void SetOffset(uint offs)
3734 layout = new FieldLayout(this,offs);
3738 /// Set the marshalling info for a field
3740 /// <param name="mInf"></param>
3741 public void SetMarshalInfo(NativeType marshallType)
3743 flags |= (ushort) FieldAttr.HasFieldMarshal;
3744 marshalInfo = new FieldMarshal(this,marshallType);
3747 internal sealed override void BuildTables(MetaData md)
3750 nameIx = md.AddToStringsHeap(name);
3751 MemoryStream sig = new MemoryStream();
3752 sig.WriteByte(FieldSig);
3754 sigIx = md.AddToBlobHeap(sig.ToArray());
3756 md.AddToTable(MDTable.FieldRVA,rva);
3757 rva.BuildTables(md);
3758 } else if (constVal != null) {
3759 md.AddToTable(MDTable.Constant,constVal);
3760 constVal.BuildTables(md);
3762 if (layout != null) md.AddToTable(MDTable.FieldLayout,layout);
3763 if (marshalInfo != null) {
3764 md.AddToTable(MDTable.FieldMarshal,marshalInfo);
3765 marshalInfo.BuildTables(md);
3770 internal sealed override uint Size(MetaData md)
3772 return 2 + md.StringsIndexSize() + md.BlobIndexSize();
3775 internal sealed override void Write(FileImage output)
3777 output.Write(flags);
3778 output.StringsIndex(nameIx);
3779 output.BlobIndex(sigIx);
3782 internal sealed override uint GetCodedIx(CIx code)
3785 case (CIx.HasConst) : return 0;
3786 case (CIx.HasCustomAttr) : return 1;
3787 case (CIx.HasFieldMarshal) : return 0;
3788 case (CIx.MemberForwarded) : return 0;
3795 /**************************************************************************/
3797 /// Descriptor for a field of a class defined in another assembly/module
3799 public class FieldRef : Field {
3801 MetaDataElement parent;
3803 internal FieldRef(MetaDataElement paren, string name, Type fType) : base(name, fType)
3808 internal sealed override void BuildTables(MetaData md)
3811 nameIx = md.AddToStringsHeap(name);
3812 MemoryStream sig = new MemoryStream();
3813 sig.WriteByte(FieldSig);
3815 sigIx = md.AddToBlobHeap(sig.ToArray());
3819 internal sealed override uint Size(MetaData md)
3821 return md.CodedIndexSize(CIx.MemberRefParent) + md.StringsIndexSize() + md.BlobIndexSize();
3824 internal sealed override void Write(FileImage output)
3826 output.WriteCodedIndex(CIx.MemberRefParent,parent);
3827 output.StringsIndex(nameIx);
3828 output.BlobIndex(sigIx);
3831 internal sealed override uint GetCodedIx(CIx code) { return 6; }
3835 /**************************************************************************/
3837 /// Base class for Method Descriptors
3840 public abstract class Method : Member {
3842 internal Method (string methName) : base (methName)
3845 public abstract void AddCallConv(CallConv cconv);
3846 internal abstract void TypeSig(MemoryStream sig);
3847 internal abstract uint GetSigIx(MetaData md);
3850 /**************************************************************************/
3852 /// Descriptor for a method defined in THIS assembly/module
3856 public class MethodDef : Method {
3858 private static readonly ushort PInvokeImpl = 0x2000;
3859 //private static readonly uint UnmanagedExport = 0x0008;
3860 // private static readonly byte LocalSigByte = 0x7;
3861 uint parIx = 0, textOffset = 0;
3862 private CallConv callConv = CallConv.Default;
3863 private int gen_param_count;
3866 CILInstructions code;
3870 ushort methFlags = 0, implFlags = 0;
3871 int maxStack = 0, numPars = 0;
3872 bool entryPoint = false;
3874 ArrayList varArgSigList;
3875 ImplMap pinvokeImpl;
3878 internal MethodDef (MetaData md, string name, Param ret_param, Param [] pars)
3879 : this (md, 0, 0, name, ret_param, pars)
3883 internal MethodDef (MetaData md, MethAttr mAttrSet, ImplAttr iAttrSet, string name,
3884 Param ret_param, Param [] pars)
3887 methFlags = (ushort)mAttrSet;
3888 implFlags = (ushort)iAttrSet;
3889 this.ret_param = ret_param;
3892 if (parList != null)
3893 numPars = parList.Length;
3894 tabIx = MDTable.Method;
3897 internal Param[] GetPars()
3902 internal override uint GetSigIx(MetaData md)
3904 MemoryStream sig = new MemoryStream();
3906 return md.AddToBlobHeap(sig.ToArray());
3909 public override void AddCallConv(CallConv cconv)
3915 /// Add some attributes to this method descriptor
3917 /// <param name="ma">the attributes to be added</param>
3918 public void AddMethAttribute(MethAttr ma)
3920 methFlags |= (ushort)ma;
3924 /// Add some implementation attributes to this method descriptor
3926 /// <param name="ia">the attributes to be added</param>
3927 public void AddImplAttribute(ImplAttr ia)
3929 implFlags |= (ushort)ia;
3932 public void AddPInvokeInfo(ModuleRef scope, string methName,
3933 PInvokeAttr callAttr) {
3934 pinvokeImpl = new ImplMap((ushort)callAttr,this,methName,scope);
3935 methFlags |= PInvokeImpl;
3939 /// Add a named generic type parameter
3941 public GenericParameter AddGenericParameter (short index, string name)
3943 return AddGenericParameter (index, name, 0);
3947 /// Add a named generic type parameter with attributes
3949 public GenericParameter AddGenericParameter (short index, string name, GenericParamAttributes attr)
3951 GenericParameter gp = new GenericParameter (this, metaData, index, name, attr);
3952 metaData.AddToTable (MDTable.GenericParam, gp);
3958 /// Set the maximum stack height for this method
3960 /// <param name="maxStack">the maximum height of the stack</param>
3961 public void SetMaxStack(int maxStack)
3963 this.maxStack = maxStack;
3967 /// Add local variables to this method
3969 /// <param name="locals">the locals to be added</param>
3970 /// <param name="initLocals">are locals initialised to default values</param>
3971 public void AddLocals(Local[] locals, bool initLocals)
3973 this.locals = locals;
3974 this.initLocals = initLocals;
3977 /* Add Marshal info for return type */
3978 public void AddRetTypeMarshallInfo (NativeType marshallType)
3980 ret_param.AddMarshallInfo (marshallType);
3984 /// Mark this method as having an entry point
3986 public void DeclareEntryPoint()
3992 /// Create a code buffer for this method to add the IL instructions to
3994 /// <returns>a buffer for this method's IL instructions</returns>
3995 public CILInstructions CreateCodeBuffer()
3997 code = new CILInstructions(metaData);
4002 /// Make a method reference descriptor for this method to be used
4003 /// as a callsite signature for this vararg method
4005 /// <param name="optPars">the optional pars for the vararg method call</param>
4006 /// <returns></returns>
4007 public MethodRef MakeVarArgSignature(Type[] optPars)
4009 Type[] pars = new Type[numPars];
4010 MethodRef varArgSig;
4011 for (int i=0; i < numPars; i++) {
4012 pars[i] = parList[i].GetParType();
4014 varArgSig = new MethodRef (this, name, ret_param.GetParType (), pars, true, optPars, 0);
4016 if (varArgSigList == null)
4017 varArgSigList = new ArrayList ();
4018 varArgSigList.Add (varArgSig);
4022 internal sealed override void TypeSig(MemoryStream sig)
4024 sig.WriteByte((byte)callConv);
4025 if ((callConv & CallConv.Generic) == CallConv.Generic)
4026 MetaData.CompressNum ((uint) gen_param_count, sig);
4027 MetaData.CompressNum((uint)numPars,sig);
4029 ret_param.seqNo = 0;
4030 ret_param.TypeSig (sig);
4031 for (ushort i=0; i < numPars; i++) {
4032 parList[i].seqNo = (ushort)(i+1);
4033 parList[i].TypeSig(sig);
4037 internal sealed override void BuildTables(MetaData md)
4040 if (pinvokeImpl != null) {
4041 md.AddToTable(MDTable.ImplMap,pinvokeImpl);
4042 pinvokeImpl.BuildTables(md);
4044 if (entryPoint) md.SetEntryPoint(this);
4046 if (locals != null) {
4047 localSig = new LocalSig(locals);
4048 md.AddToTable(MDTable.StandAloneSig,localSig);
4049 localSig.BuildTables(md);
4050 locToken = localSig.Token();
4053 code.CheckCode(locToken,initLocals,maxStack);
4054 textOffset = md.AddCode(code);
4056 nameIx = md.AddToStringsHeap(name);
4057 sigIx = GetSigIx(md);
4058 parIx = md.TableIndex(MDTable.Param);
4059 if (ret_param.HasMarshalInfo || ret_param.HasCustomAttr) {
4060 md.AddToTable(MDTable.Param, ret_param);
4061 ret_param.BuildTables(md);
4063 for (int i=0; i < numPars; i++) {
4064 md.AddToTable(MDTable.Param,parList[i]);
4065 parList[i].BuildTables(md);
4067 if (varArgSigList != null) {
4068 foreach (MethodRef varArgSig in varArgSigList) {
4069 md.AddToTable(MDTable.MemberRef,varArgSig);
4070 varArgSig.BuildTables(md);
4073 // Console.WriteLine("method has " + numPars + " parameters");
4077 internal sealed override uint Size(MetaData md)
4079 return 8 + md.StringsIndexSize() + md.BlobIndexSize() + md.TableIndexSize(MDTable.Param);
4082 internal sealed override void Write(FileImage output)
4084 if (ZeroRva ()) output.Write(0);
4085 else output.WriteCodeRVA(textOffset);
4086 output.Write(implFlags);
4087 output.Write(methFlags);
4088 output.StringsIndex(nameIx);
4089 output.BlobIndex(sigIx);
4090 output.WriteIndex(MDTable.Param,parIx);
4093 internal bool ZeroRva ()
4095 return (((methFlags & (ushort)MethAttr.Abstract) != 0) ||
4096 ((implFlags & (ushort)ImplAttr.Runtime) != 0) ||
4097 ((implFlags & (ushort)ImplAttr.InternalCall) != 0) ||
4098 (pinvokeImpl != null)); // TODO: Not entirely true but works for now
4101 internal sealed override uint GetCodedIx(CIx code)
4104 case (CIx.HasCustomAttr) : return 0;
4105 case (CIx.HasDeclSecurity) : return 1;
4106 case (CIx.MemberRefParent) : return 3;
4107 case (CIx.MethodDefOrRef) : return 0;
4108 case (CIx.MemberForwarded) : return 1;
4109 case (CIx.CustomAttributeType) : return 2;
4110 case (CIx.TypeOrMethodDef) : return 1;
4116 /**************************************************************************/
4118 /// Descriptor for a method defined in another assembly/module
4120 public class MethodRef : Method {
4122 private static readonly byte Sentinel = 0x41;
4123 Type[] parList, optParList;
4124 MetaDataElement parent;
4125 uint numPars = 0, numOptPars = 0;
4126 CallConv callConv = CallConv.Default;
4128 int gen_param_count;
4130 internal MethodRef(MetaDataElement paren, string name, Type retType,
4131 Type[] pars, bool varArgMeth, Type[] optPars, int gen_param_count) : base(name)
4135 this.retType = retType;
4136 if (parList != null) numPars = (uint)parList.Length;
4138 optParList = optPars;
4139 if (optParList != null) numOptPars = (uint)optParList.Length;
4140 callConv = CallConv.Vararg;
4142 this.gen_param_count = gen_param_count;
4145 internal override uint GetSigIx(MetaData md)
4147 MemoryStream sig = new MemoryStream();
4149 return md.AddToBlobHeap(sig.ToArray());
4152 public override void AddCallConv(CallConv cconv)
4157 internal sealed override void TypeSig(MemoryStream sig)
4159 sig.WriteByte((byte)callConv);
4160 if ((callConv & CallConv.Generic) == CallConv.Generic)
4161 MetaData.CompressNum ((uint) gen_param_count, sig);
4162 MetaData.CompressNum(numPars+numOptPars,sig);
4163 retType.TypeSig(sig);
4164 for (int i=0; i < numPars; i++) {
4165 parList[i].TypeSig(sig);
4167 if (numOptPars > 0) {
4168 sig.WriteByte(Sentinel);
4169 for (int i=0; i < numOptPars; i++) {
4170 optParList[i].TypeSig(sig);
4175 internal sealed override void BuildTables(MetaData md)
4178 nameIx = md.AddToStringsHeap(name);
4179 sigIx = GetSigIx(md);
4183 internal sealed override uint Size(MetaData md)
4185 return md.CodedIndexSize(CIx.MemberRefParent) + md.StringsIndexSize() + md.BlobIndexSize();
4188 internal sealed override void Write(FileImage output)
4190 output.WriteCodedIndex(CIx.MemberRefParent,parent);
4191 output.StringsIndex(nameIx);
4192 output.BlobIndex(sigIx);
4195 internal sealed override uint GetCodedIx(CIx code)
4198 case (CIx.HasCustomAttr) : return 6;
4199 case (CIx.MethodDefOrRef) : return 1;
4200 case (CIx.CustomAttributeType) : return 3;
4208 /**************************************************************************/
4210 /// Descriptors for native types used for marshalling
4212 public class NativeType {
4213 public static readonly NativeType Void = new NativeType(0x01);
4214 public static readonly NativeType Boolean = new NativeType(0x02);
4215 public static readonly NativeType Int8 = new NativeType(0x03);
4216 public static readonly NativeType UInt8 = new NativeType(0x04);
4217 public static readonly NativeType Int16 = new NativeType(0x05);
4218 public static readonly NativeType UInt16 = new NativeType(0x06);
4219 public static readonly NativeType Int32 = new NativeType(0x07);
4220 public static readonly NativeType UInt32 = new NativeType(0x08);
4221 public static readonly NativeType Int64 = new NativeType(0x09);
4222 public static readonly NativeType UInt64 = new NativeType(0x0A);
4223 public static readonly NativeType Float32 = new NativeType(0x0B);
4224 public static readonly NativeType Float64 = new NativeType(0x0C);
4225 public static readonly NativeType Currency = new NativeType(0x0F);
4226 public static readonly NativeType BStr = new NativeType(0x13);
4227 public static readonly NativeType LPStr = new NativeType(0x14);
4228 public static readonly NativeType LPWStr = new NativeType(0x15);
4229 public static readonly NativeType LPTStr = new NativeType(0x16);
4230 public static readonly NativeType FixedSysString = new NativeType(0x17);
4231 public static readonly NativeType IUnknown = new NativeType(0x19);
4232 public static readonly NativeType IDispatch = new NativeType(0x1A);
4233 public static readonly NativeType Struct = new NativeType(0x1B);
4234 public static readonly NativeType Interface = new NativeType(0x1C);
4235 public static readonly NativeType Int = new NativeType(0x1F);
4236 public static readonly NativeType UInt = new NativeType(0x20);
4237 public static readonly NativeType ByValStr = new NativeType(0x22);
4238 public static readonly NativeType AnsiBStr = new NativeType(0x23);
4239 public static readonly NativeType TBstr = new NativeType(0x24);
4240 public static readonly NativeType VariantBool = new NativeType(0x25);
4241 public static readonly NativeType FuncPtr = new NativeType(0x26);
4242 public static readonly NativeType AsAny = new NativeType(0x28);
4243 public static readonly NativeType LPStruct = new NativeType(0x2b);
4244 public static readonly NativeType Error = new NativeType(0x2d);
4246 protected byte typeIndex;
4248 internal NativeType(byte tyIx) { typeIndex = tyIx; }
4249 internal byte GetTypeIndex() { return typeIndex; }
4251 internal virtual byte[] ToBlob()
4253 byte[] bytes = new byte[1];
4254 bytes[0] = GetTypeIndex();
4260 public class FixedSysString : NativeType {
4264 public FixedSysString (uint size) : base (NativeType.FixedSysString.GetTypeIndex ())
4269 internal override byte [] ToBlob ()
4271 MemoryStream str = new MemoryStream ();
4272 str.WriteByte (GetTypeIndex ());
4273 MetaData.CompressNum (size, str);
4274 return str.ToArray ();
4279 public class NativeArray : NativeType {
4281 NativeType elemType;
4282 int numElem = -1, parNum = -1, elemMult = -1;
4284 public NativeArray(NativeType elemType) : this (elemType, -1, -1, -1)
4286 this.elemType = elemType;
4289 /* public NativeArray(NativeType elemType, int len) : base(0x2A) {
4290 this.elemType = elemType;
4295 public NativeArray(NativeType elemType, int numElem, int parNumForLen, int elemMult) : base(0x2A)
4297 this.elemType = elemType;
4298 this.numElem = numElem;
4299 parNum = parNumForLen;
4300 this.elemMult = elemMult;
4303 public NativeArray(NativeType elemType, int numElem, int parNumForLen)
4304 : this (elemType, numElem, parNumForLen, -1)
4308 internal override byte[] ToBlob()
4310 MemoryStream str = new MemoryStream();
4311 str.WriteByte(GetTypeIndex());
4312 if (elemType == null) str.WriteByte(0x50); // no info (MAX)
4313 else str.WriteByte(elemType.GetTypeIndex());
4315 /* see : mono/metadata/metadata.c:mono_metadata_parse_marshal_spec
4316 * LAMESPEC: Older spec versions say elemMult comes before
4317 * len. Newer spec versions don't talk about elemMult at
4318 * all, but csc still emits it, and it is used to distinguish
4319 * between parNum being 0, and parNum being omitted.
4324 return str.ToArray ();
4326 MetaData.CompressNum((uint) parNum,str);
4327 if (numElem != -1) {
4328 MetaData.CompressNum ((uint) numElem, str);
4330 // <native_type> [ int32 ]
4331 MetaData.CompressNum((uint) elemMult,str);
4332 //else <native_type> [ int32 + int32 ]
4333 } else if (elemMult != -1) {
4334 // When can this occur ?
4335 MetaData.CompressNum (0, str);
4336 MetaData.CompressNum((uint) elemMult,str);
4338 //else <native_type> [ + int32 ]
4340 return str.ToArray();
4345 public class SafeArray : NativeType {
4347 SafeArrayType elemType;
4350 public SafeArray() : base(0x1D)
4354 public SafeArray(SafeArrayType elemType) : base(0x1D)
4356 this.elemType = elemType;
4360 internal override byte[] ToBlob()
4362 byte[] bytes = new byte[hasElemType ? 2 : 1];
4363 bytes[0] = GetTypeIndex();
4365 bytes[1] = (byte)elemType;
4371 public class FixedArray : NativeType {
4375 //public FixedArray(NativeType elemType, int numElems) : base(0x1E) {
4376 public FixedArray(int numElems) : base(0x1E)
4378 //this.elemType = elemType;
4379 numElem = (uint)numElems;
4382 internal override byte[] ToBlob()
4384 MemoryStream str = new MemoryStream();
4385 str.WriteByte(GetTypeIndex());
4386 MetaData.CompressNum(numElem,str);
4388 fixed array [5] lpstr [2]
4389 This format is not supported by ilasm 1.1.4322.2032,
4390 but is supported by 2.0.5125..
4391 ilasm 1.1 only supports "fixed array [5]"
4392 if (elemType == null) str.WriteByte(0x50); // no info (MAX)
4393 else str.WriteByte(elemType.GetTypeIndex());*/
4395 return str.ToArray();
4400 public class CustomMarshaller : NativeType {
4403 string marshallerName;
4406 public CustomMarshaller(string typeNameOrGUID, string marshallerName,
4407 string optCookie) : base(0x2C)
4409 typeName = typeNameOrGUID;
4410 this.marshallerName = marshallerName;
4414 public CustomMarshaller(string marshallerName, string optCookie)
4415 :this (null, marshallerName, optCookie)
4419 internal override byte[] ToBlob()
4421 MemoryStream str = new MemoryStream();
4422 BinaryWriter bw = new BinaryWriter(str,new UTF8Encoding());
4423 bw.Write(GetTypeIndex());
4424 //Native type name & unmanaged type - unused
4425 //See mono/metadata/metadata.c : mono_metadata_parse_marshal_spec
4426 bw.Write ((byte) 0); // Native Type name, unused
4427 bw.Write ((byte) 0); // Unmanaged type, unused
4428 if (marshallerName != null) {
4429 MetaData.CompressNum ((uint)marshallerName.Length, str);
4430 bw.Write(marshallerName.ToCharArray());
4432 bw.Write ((byte) 0);
4434 if (cookie != null) {
4435 MetaData.CompressNum ((uint)cookie.Length, str);
4436 bw.Write(cookie.ToCharArray());
4438 bw.Write ((byte) 0);
4441 return str.ToArray();
4445 /**************************************************************************/
4447 /// Descriptor for the Primitive types defined in IL
4449 public class PrimitiveType : Type {
4451 private string name;
4452 private int systemTypeIndex;
4453 public static int NumSystemTypes = 18;
4455 public static readonly PrimitiveType Void = new PrimitiveType(0x01,"Void",0);
4456 public static readonly PrimitiveType Boolean = new PrimitiveType(0x02,"Boolean",1);
4457 public static readonly PrimitiveType Char = new PrimitiveType(0x03,"Char",2);
4458 public static readonly PrimitiveType Int8 = new PrimitiveType(0x04,"SByte",3);
4459 public static readonly PrimitiveType UInt8 = new PrimitiveType(0x05,"Byte",4);
4460 public static readonly PrimitiveType Int16 = new PrimitiveType(0x06,"Int16",5);
4461 public static readonly PrimitiveType UInt16 = new PrimitiveType(0x07,"UInt16",6);
4462 public static readonly PrimitiveType Int32 = new PrimitiveType(0x08,"Int32",7);
4463 public static readonly PrimitiveType UInt32 = new PrimitiveType(0x09,"UInt32",8);
4464 public static readonly PrimitiveType Int64 = new PrimitiveType(0x0A,"Int64",9);
4465 public static readonly PrimitiveType UInt64 = new PrimitiveType(0x0B,"UInt64",10);
4466 public static readonly PrimitiveType Float32 = new PrimitiveType(0x0C,"Single",11);
4467 public static readonly PrimitiveType Float64 = new PrimitiveType(0x0D,"Double",12);
4468 public static readonly PrimitiveType String = new PrimitiveType(0x0E,"String",13);
4469 internal static readonly PrimitiveType Class = new PrimitiveType(0x12);
4470 internal static readonly PrimitiveType Var = new PrimitiveType(0x13);
4471 internal static readonly PrimitiveType GenericInst = new PrimitiveType(0x15);
4472 public static readonly PrimitiveType TypedRef = new PrimitiveType(0x16,"TypedReference",14);
4473 public static readonly PrimitiveType IntPtr = new PrimitiveType(0x18,"IntPtr",15);
4474 public static readonly PrimitiveType UIntPtr = new PrimitiveType(0x19,"UIntPtr",16);
4475 public static readonly PrimitiveType Object = new PrimitiveType(0x1C,"Object",17);
4476 internal static readonly PrimitiveType ClassType = new PrimitiveType(0x50);
4477 internal static readonly PrimitiveType SZArray = new PrimitiveType(0x1D);
4478 internal static readonly PrimitiveType MVar = new PrimitiveType(0x1E);
4479 internal static readonly PrimitiveType ValueType = new PrimitiveType(0x11, "ValueType", 18);
4480 public static readonly PrimitiveType NativeInt = IntPtr;
4481 public static readonly PrimitiveType NativeUInt = UIntPtr;
4483 internal PrimitiveType(byte typeIx) : base(typeIx) { }
4485 internal PrimitiveType(byte typeIx, string name, int STIx) : base(typeIx)
4488 this.systemTypeIndex = STIx;
4491 internal string GetName() { return name; }
4493 internal int GetSystemTypeIx() { return systemTypeIndex; }
4495 internal sealed override void TypeSig(MemoryStream str)
4497 str.WriteByte(typeIndex);
4500 internal override MetaDataElement GetTypeSpec(MetaData md)
4502 TypeSpec tS = md.GetPrimitiveTypeSpec(systemTypeIndex);
4504 tS = new TypeSpec(this,md);
4505 md.SetPrimitiveTypeSpec(systemTypeIndex,tS);
4506 md.AddToTable(MDTable.TypeSpec,tS);
4513 public class PrimitiveTypeRef : Type
4518 internal PrimitiveTypeRef(PrimitiveType type, MetaData md)
4525 internal uint TypeDefOrRefToken()
4527 uint cIx = type.GetTypeSpec (metaData).Row;
4528 cIx = (cIx << 2) | 0x2;
4533 /**************************************************************************/
4535 /// Descriptor for an pointer (type * or type &)
4537 public abstract class PtrType : Type {
4541 internal PtrType(Type bType, byte typeIx) : base(typeIx)
4544 tabIx = MDTable.TypeSpec;
4547 internal sealed override void TypeSig(MemoryStream str)
4549 str.WriteByte(typeIndex);
4550 baseType.TypeSig(str);
4554 /**************************************************************************/
4556 /// Descriptor for a managed pointer (type & or byref)
4559 public class ManagedPointer : PtrType {
4562 /// Create new managed pointer to baseType
4564 /// <param name="bType">the base type of the pointer</param>
4565 public ManagedPointer(Type baseType) : base(baseType,0x10) { }
4568 /**************************************************************************/
4570 /// Descriptor for an unmanaged pointer (type *)
4572 public class UnmanagedPointer : PtrType {
4575 /// Create a new unmanaged pointer to baseType
4577 /// <param name="baseType">the base type of the pointer</param>
4578 public UnmanagedPointer(Type baseType) : base(baseType, 0x0F) { }
4582 /**************************************************************************/
4584 public interface IExternRef {
4585 ClassRef AddClass(string nsName, string name);
4586 ClassRef AddValueClass(string nsName, string name);
4590 /// A reference to an external assembly (.assembly extern)
4592 public class AssemblyRef : ResolutionScope, IExternRef {
4594 private ushort major, minor, build, revision;
4595 uint flags, keyIx, hashIx, cultIx;
4596 bool hasVersion = false, isKeyToken = false;
4600 internal AssemblyRef(MetaData md, string name) : base(name,md)
4602 tabIx = MDTable.AssemblyRef;
4605 public void AddAssemblyAttr (AssemAttr aa)
4611 /// Add version information about this external assembly
4613 /// <param name="majVer">Major Version</param>
4614 /// <param name="minVer">Minor Version</param>
4615 /// <param name="bldNo">Build Number</param>
4616 /// <param name="revNo">Revision Number</param>
4617 public void AddVersionInfo(int majVer, int minVer, int bldNo, int revNo)
4619 major = (ushort)majVer;
4620 minor = (ushort)minVer;
4621 build = (ushort)bldNo;
4622 revision = (ushort)revNo;
4627 /// Add the hash value for this external assembly
4629 /// <param name="hash">bytes of the hash value</param>
4630 public void AddHash(byte[] hash)
4632 hashIx = metaData.AddToBlobHeap(hash);
4636 /// Set the culture for this external assembly
4638 /// <param name="cult">the culture string</param>
4639 public void AddCulture(string cult)
4641 cultIx = metaData.AddToStringsHeap(cult);
4646 /// Add the full public key for this external assembly
4648 /// <param name="key">bytes of the public key</param>
4649 public void AddKey(byte[] key)
4651 flags |= 0x0001; // full public key
4653 keyIx = metaData.AddToBlobHeap(key);
4657 /// Add the public key token (low 8 bytes of the public key)
4659 /// <param name="key">low 8 bytes of public key</param>
4660 public void AddKeyToken(byte[] key)
4662 keyIx = metaData.AddToBlobHeap(key);
4668 /// Add a class to this external assembly
4670 /// <param name="nsName">name space name</param>
4671 /// <param name="name">class name</param>
4672 /// <returns></returns>
4673 public virtual ClassRef AddClass(string nsName, string name)
4675 ClassRef aClass = new ClassRef(nsName,name,metaData);
4676 metaData.AddToTable(MDTable.TypeRef,aClass);
4677 aClass.SetParent(this);
4682 /// Add a value class to this external assembly
4684 /// <param name="nsName">name space name</param>
4685 /// <param name="name">class name</param>
4686 /// <returns></returns>
4687 public virtual ClassRef AddValueClass(string nsName, string name)
4689 ClassRef aClass = new ClassRef(nsName,name,metaData);
4690 metaData.AddToTable(MDTable.TypeRef,aClass);
4691 aClass.SetParent(this);
4692 aClass.MakeValueClass(ValueClass.ValueType);
4696 internal string TypeName()
4698 string result = name;
4700 result = result + ", Version=" + major + "." + minor + "." +
4701 build + "." + revision;
4702 if (keyBytes != null) {
4703 string tokenStr = "=";
4704 if (isKeyToken) tokenStr = "Token=";
4705 result = result + ", PublicKey" + tokenStr;
4706 for (int i=0; i < keyBytes.Length; i++) {
4707 result = result + Hex.Byte(keyBytes[i]);
4710 if (culture != null)
4711 result = result + ", Culture=" + culture;
4715 internal sealed override uint Size(MetaData md)
4717 return 12 + 2 * md.StringsIndexSize() + 2 * md.BlobIndexSize();
4720 internal sealed override void Write(FileImage output)
4722 output.Write(major);
4723 output.Write(minor);
4724 output.Write(build);
4725 output.Write(revision);
4726 output.Write(flags);
4727 output.BlobIndex(keyIx);
4728 output.StringsIndex(nameIx);
4729 output.StringsIndex(cultIx);
4730 output.BlobIndex(hashIx);
4733 internal sealed override uint GetCodedIx(CIx code)
4736 case (CIx.ResolutionScope) : return 2;
4737 case (CIx.HasCustomAttr) : return 15;
4738 case (CIx.Implementation) : return 1;
4745 /**************************************************************************/
4747 /// Descriptor for a class defined in System (mscorlib)
4749 internal class SystemClass : ClassRef {
4751 PrimitiveType elemType;
4753 internal SystemClass(PrimitiveType eType, AssemblyRef paren, MetaData md)
4754 : base("System",eType.GetName(),md) {
4759 internal override sealed MetaDataElement GetTypeSpec(MetaData md)
4761 if (typeSpec == null) typeSpec = (TypeSpec)elemType.GetTypeSpec(md);
4766 internal sealed override void TypeSig(MemoryStream str)
4768 str.WriteByte(elemType.GetTypeIndex());
4773 /**************************************************************************/
4775 /// The assembly for mscorlib.
4777 public sealed class MSCorLib : AssemblyRef {
4779 private static readonly int valueTypeIx = 18;
4780 private readonly string systemName = "System";
4781 private Class[] systemClasses = new Class[valueTypeIx+2];
4782 private PrimitiveType[] systemTypes = new PrimitiveType[valueTypeIx];
4784 private static int[] specialNames = {
4785 PrimitiveType.Void.GetName().GetHashCode(),
4786 PrimitiveType.Boolean.GetName().GetHashCode(),
4787 PrimitiveType.Char.GetName().GetHashCode(),
4788 PrimitiveType.Int8.GetName().GetHashCode(),
4789 PrimitiveType.UInt8.GetName().GetHashCode(),
4790 PrimitiveType.Int16.GetName().GetHashCode(),
4791 PrimitiveType.UInt16.GetName().GetHashCode(),
4792 PrimitiveType.Int32.GetName().GetHashCode(),
4793 PrimitiveType.UInt32.GetName().GetHashCode(),
4794 PrimitiveType.Int64.GetName().GetHashCode(),
4795 PrimitiveType.UInt64.GetName().GetHashCode(),
4796 PrimitiveType.Float32.GetName().GetHashCode(),
4797 PrimitiveType.Float64.GetName().GetHashCode(),
4798 PrimitiveType.String.GetName().GetHashCode(),
4799 PrimitiveType.TypedRef.GetName().GetHashCode(),
4800 PrimitiveType.IntPtr.GetName().GetHashCode(),
4801 PrimitiveType.UIntPtr.GetName().GetHashCode(),
4802 PrimitiveType.Object.GetName().GetHashCode(),
4803 PrimitiveType.ValueType.GetName ().GetHashCode(),
4804 "Enum".GetHashCode()
4807 internal MSCorLib(MetaData md) : base(md,"mscorlib")
4809 if (!PEFile.IsMSCorlib)
4810 md.AddToTable(MDTable.AssemblyRef,this);
4811 systemTypes[PrimitiveType.Void.GetSystemTypeIx()] = PrimitiveType.Void;
4812 systemTypes[PrimitiveType.Boolean.GetSystemTypeIx()] = PrimitiveType.Boolean;
4813 systemTypes[PrimitiveType.Char.GetSystemTypeIx()] = PrimitiveType.Char;
4814 systemTypes[PrimitiveType.Int8.GetSystemTypeIx()] = PrimitiveType.Int8;
4815 systemTypes[PrimitiveType.UInt8.GetSystemTypeIx()] = PrimitiveType.UInt8;
4816 systemTypes[PrimitiveType.Int16.GetSystemTypeIx()] = PrimitiveType.Int16;
4817 systemTypes[PrimitiveType.UInt16.GetSystemTypeIx()] = PrimitiveType.UInt16;
4818 systemTypes[PrimitiveType.Int32.GetSystemTypeIx()] = PrimitiveType.Int32;
4819 systemTypes[PrimitiveType.UInt32.GetSystemTypeIx()] = PrimitiveType.UInt32;
4820 systemTypes[PrimitiveType.Int64.GetSystemTypeIx()] = PrimitiveType.Int64;
4821 systemTypes[PrimitiveType.UInt64.GetSystemTypeIx()] = PrimitiveType.UInt64;
4822 systemTypes[PrimitiveType.Float32.GetSystemTypeIx()] = PrimitiveType.Float32;
4823 systemTypes[PrimitiveType.Float64.GetSystemTypeIx()] = PrimitiveType.Float64;
4824 systemTypes[PrimitiveType.IntPtr.GetSystemTypeIx()] = PrimitiveType.IntPtr;
4825 systemTypes[PrimitiveType.UIntPtr.GetSystemTypeIx()] = PrimitiveType.UIntPtr;
4826 systemTypes[PrimitiveType.String.GetSystemTypeIx()] = PrimitiveType.String;
4827 systemTypes[PrimitiveType.Object.GetSystemTypeIx()] = PrimitiveType.Object;
4828 systemTypes[PrimitiveType.TypedRef.GetSystemTypeIx()] = PrimitiveType.TypedRef;
4832 /// Add a class to the mscorlib assembly
4834 /// <param name="nsName">name space name</param>
4835 /// <param name="name">class name</param>
4836 /// <returns></returns>
4837 public override ClassRef AddClass(string nsName, string name)
4839 /* This gets called by !mscorlib, for adding references INTO mscorlib, so
4840 it should be returning ClassRef ..*/
4841 Class aClass = GetSpecialClass(nsName,name);
4842 if (aClass == null) {
4843 aClass = new ClassRef(nsName,name,metaData);
4844 metaData.AddToTable(MDTable.TypeRef,aClass);
4845 if (aClass is ClassRef)
4846 ((ClassRef) aClass).SetParent(this);
4848 //FIXME: Check for !ClassRef here?
4849 return (ClassRef) aClass;
4852 private Class GetSpecialClass(string nsName,string name)
4854 if (nsName.CompareTo(systemName) != 0) return null;
4855 int hash = name.GetHashCode();
4856 for (int i=0; i < specialNames.Length; i++) {
4857 if (hash != specialNames[i])
4859 if (systemClasses[i] == null) {
4860 if (i < valueTypeIx) {
4861 systemClasses[i] = new SystemClass(systemTypes[i],this,metaData);
4862 if ((systemTypes[i] != PrimitiveType.Object) &&
4863 (systemTypes[i] != PrimitiveType.String)) {
4864 systemClasses[i].MakeValueClass(ValueClass.ValueType);
4867 systemClasses[i] = new ClassRef(nsName,name,metaData);
4868 ((ClassRef) systemClasses[i]).SetParent(this);
4869 if (!ClassDef.IsValueType (nsName, name) && !ClassDef.IsEnum (nsName, name))
4870 systemClasses[i].MakeValueClass(ValueClass.ValueType);
4872 metaData.AddToTable(MDTable.TypeRef,systemClasses[i]);
4874 return systemClasses[i];
4879 internal void SetSpecialSystemClass (string nsName, string name, Class aClass)
4881 if (nsName != systemName) return;
4882 int hash = name.GetHashCode ();
4883 for (int i = 0; i < specialNames.Length; i++) {
4884 if (hash != specialNames [i])
4886 if (systemClasses [i] == null) {
4887 systemClasses [i] = aClass;
4892 internal Class GetSpecialSystemClass(PrimitiveType pType)
4894 int ix = pType.GetSystemTypeIx();
4895 if (systemClasses[ix] == null && !PEFile.IsMSCorlib) {
4896 systemClasses[ix] = new SystemClass(pType,this,metaData);
4897 metaData.AddToTable(MDTable.TypeRef,systemClasses[ix]);
4899 return systemClasses[ix];
4902 private ClassRef GetValueClass(string name, int hash)
4904 /* Called by MSCorLib.AddValueClass, which is called by
4905 !mscorlib, for adding ref to value class INTO mscorlib,
4906 so this should be classref */
4907 int ix = valueTypeIx;
4908 if (hash != specialNames[valueTypeIx]) ix++;
4909 if (systemClasses[ix] == null) {
4910 systemClasses[ix] = new ClassRef(systemName,name,metaData);
4911 ((ClassRef) systemClasses[ix]).SetParent(this);
4912 ((ClassRef) systemClasses[ix]).MakeValueClass(ValueClass.ValueType);
4913 metaData.AddToTable(MDTable.TypeRef,systemClasses[ix]);
4915 return (ClassRef) systemClasses[ix];
4918 internal Class ValueType()
4920 if (systemClasses[valueTypeIx] == null && !PEFile.IsMSCorlib) {
4921 ClassRef valType = new ClassRef("System","ValueType",metaData);
4922 valType.SetParent(this);
4923 valType.MakeValueClass(ValueClass.ValueType);
4924 metaData.AddToTable(MDTable.TypeRef,valType);
4925 systemClasses[valueTypeIx] = valType;
4927 return systemClasses[valueTypeIx];
4930 internal Class EnumType()
4932 /* Called by both mscorlib & !mscorlib, so can be
4933 either ClassRef or ClassDef */
4934 //systemClasses [ valueTypeIx + 1] -> System.Enum
4935 if (systemClasses[valueTypeIx + 1] == null && !PEFile.IsMSCorlib) {
4936 ClassRef valType = new ClassRef("System","Enum",metaData);
4937 valType.SetParent(this);
4938 valType.MakeValueClass(ValueClass.Enum);
4939 metaData.AddToTable(MDTable.TypeRef,valType);
4940 systemClasses[valueTypeIx + 1] = valType;
4942 return systemClasses[valueTypeIx + 1];
4946 /// Add a value class to this external assembly
4948 /// <param name="nsName">name space name</param>
4949 /// <param name="name">class name</param>
4950 /// <returns></returns>
4951 public override ClassRef AddValueClass(string nsName, string name)
4953 if (nsName.CompareTo(systemName) == 0) {
4954 int hash = name.GetHashCode();
4955 if ((hash == specialNames[valueTypeIx]) ||
4956 (hash == specialNames[valueTypeIx+1])) {
4957 return GetValueClass(name,hash);
4960 ClassRef aClass = new ClassRef(nsName,name,metaData);
4961 metaData.AddToTable(MDTable.TypeRef,aClass);
4962 aClass.SetParent(this);
4963 aClass.MakeValueClass(ValueClass.ValueType);
4969 /**************************************************************************/
4972 /// Root (20 bytes + UTF-8 Version String + quad align padding)
4973 /// StreamHeaders (8 bytes + null terminated name string + quad align padding)
4975 /// #~ (always present - holds metadata tables)
4976 /// #Strings (always present - holds identifier strings)
4977 /// #US (Userstring heap)
4978 /// #Blob (signature blobs)
4979 /// #GUID (guids for assemblies or Modules)
4981 public class MetaData {
4983 internal static readonly int[] CIxShiftMap = {2,2,5,1,2,3,1,1,1,2,3,2,1};
4984 private static readonly byte StringsHeapMask = 0x1;
4985 private static readonly byte GUIDHeapMask = 0x2;
4986 private static readonly byte BlobHeapMask = 0x4;
4987 private static readonly uint MetaDataSignature = 0x424A5342;
4988 private static readonly uint maxSmlIxSize = 0xFFFF;
4989 private static readonly uint max1BitSmlIx = 0x7FFF;
4990 private static readonly uint max2BitSmlIx = 0x3FFF;
4991 private static readonly uint max3BitSmlIx = 0x1FFF;
4992 private static readonly uint max5BitSmlIx = 0x7FF;
4993 // NOTE: version and stream name strings MUST always be quad padded
4994 private static readonly string version = "v4.0.30319\0\0";
4995 private static readonly char[] tildeName = {'#','~','\0','\0'};
4996 private static readonly char[] stringsName = {'#','S','t','r','i','n','g','s','\0','\0','\0','\0'};
4997 private static readonly char[] usName = {'#','U','S','\0'};
4998 private static readonly char[] guidName = {'#','G','U','I','D','\0','\0','\0'};
4999 private static readonly char[] blobName = {'#','B','l','o','b','\0','\0','\0'};
5000 private static readonly uint MetaDataHeaderSize = 20 + (uint)version.Length;
5001 private static readonly uint TildeHeaderSize = 24;
5002 private static readonly uint StreamHeaderSize = 8;
5003 private static readonly uint numMetaDataTables = (int)MDTable.GenericParamConstraint + 1;
5005 MetaDataStream strings, us, guid, blob;
5007 MetaDataStream[] streams = new MetaDataStream[5];
5008 uint numStreams = 5;
5009 uint tildeTide = 0, tildePadding = 0, tildeStart = 0;
5010 uint numTables = 0, resourcesSize = 0;
5011 ArrayList[] metaDataTables = new ArrayList[numMetaDataTables];
5012 ArrayList byteCodes = new ArrayList();
5013 uint codeSize = 0, codeStart, byteCodePadding = 0, metaDataSize = 0;
5014 ulong valid = 0, /*sorted = 0x000002003301FA00;*/ sorted = 0;
5015 bool[] largeIx = new bool[numMetaDataTables];
5016 bool[] lgeCIx = new bool[(int)CIx.MaxCIx];
5017 bool largeStrings = false, largeUS = false, largeGUID = false, largeBlob = false;
5018 private FileImage file;
5019 private byte heapSizes = 0;
5020 MetaDataElement entryPoint;
5021 BinaryWriter output;
5022 public MSCorLib mscorlib;
5023 private TypeSpec[] systemTypeSpecs = new TypeSpec[PrimitiveType.NumSystemTypes];
5025 private ArrayList cattr_list;
5026 private ArrayList declsec_list;
5027 ArrayList resources;
5029 internal MetaData(FileImage file)
5031 // tilde = new MetaDataStream(tildeName,false,0);
5033 strings = new MetaDataStream(stringsName,new UTF8Encoding(),true);
5034 us = new MetaDataStream(usName,new UnicodeEncoding(),true);
5035 guid = new MetaDataStream(guidName,false);
5036 blob = new MetaDataStream(blobName,true);
5037 streams[1] = strings;
5041 for (int i=0; i < numMetaDataTables; i++) {
5044 for (int i=0; i < lgeCIx.Length; i++) {
5047 mscorlib = new MSCorLib(this);
5050 internal TypeSpec GetPrimitiveTypeSpec(int ix)
5052 return systemTypeSpecs[ix];
5055 internal void SetPrimitiveTypeSpec(int ix, TypeSpec typeSpec)
5057 systemTypeSpecs[ix] = typeSpec;
5060 internal uint Size()
5062 return metaDataSize;
5065 private void CalcHeapSizes ()
5067 if (strings.LargeIx()) {
5068 largeStrings = true;
5069 heapSizes |= StringsHeapMask;
5071 if (guid.LargeIx()) {
5073 heapSizes |= GUIDHeapMask;
5075 if (blob.LargeIx()) {
5077 heapSizes |= BlobHeapMask;
5080 largeUS = us.LargeIx();
5083 internal void StreamSize(byte mask)
5088 internal uint AddToUSHeap(string str)
5090 if (str == null) return 0;
5091 return us.Add(str,true);
5094 internal uint AddToUSHeap(byte[] str)
5096 if (str == null) return 0;
5097 return us.Add (str, true);
5100 internal uint AddToStringsHeap(string str)
5102 if ((str == null) || (str.CompareTo("") == 0)) return 0;
5103 return strings.Add(str,false);
5106 internal uint AddToGUIDHeap(Guid guidNum)
5108 return guid.Add(guidNum, false);
5111 internal uint AddToBlobHeap(byte[] blobBytes)
5113 if (blobBytes == null) return 0;
5114 return blob.Add(blobBytes, true);
5117 internal uint AddToBlobHeap(byte val)
5119 return blob.Add(val, true);
5122 internal uint AddToBlobHeap(sbyte val)
5124 return blob.Add(val, true);
5127 internal uint AddToBlobHeap(ushort val)
5129 return blob.Add(val, true);
5132 internal uint AddToBlobHeap(short val)
5134 return blob.Add(val, true);
5137 internal uint AddToBlobHeap(uint val)
5139 return blob.Add(val, true);
5142 internal uint AddToBlobHeap(int val)
5144 return blob.Add(val, true);
5147 internal uint AddToBlobHeap(ulong val)
5149 return blob.Add(val, true);
5152 internal uint AddToBlobHeap(long val)
5154 return blob.Add(val, true);
5157 internal uint AddToBlobHeap(float val)
5159 return blob.Add(val, true);
5162 internal uint AddToBlobHeap(double val)
5164 return blob.Add(val, true);
5167 internal uint AddToBlobHeap(string val)
5169 return blob.Add(val,true);
5172 internal void AddCustomAttribute (CustomAttribute cattr)
5174 if (cattr_list == null)
5175 cattr_list = new ArrayList ();
5176 cattr_list.Add (cattr);
5179 internal void AddDeclSecurity (BaseDeclSecurity decl_sec)
5181 if (declsec_list == null)
5182 declsec_list = new ArrayList ();
5183 declsec_list.Add (decl_sec);
5186 private ArrayList GetTable(MDTable tableIx)
5188 int tabIx = (int)tableIx;
5189 if (metaDataTables[tabIx] == null) {
5190 metaDataTables[tabIx] = new ArrayList();
5191 valid |= ((ulong)0x1 << tabIx);
5192 // Console.WriteLine("after creating table " + tableIx + "(" + tabIx + ") valid = " + valid);
5195 return metaDataTables[tabIx];
5198 internal void AddToTable(MDTable tableIx, MetaDataElement elem)
5201 // Console.Out.WriteLine("ERROR - element already in table " + tableIx);
5204 // updates Row field of the element
5205 // Console.WriteLine("Adding element to table " + (uint)tableIx);
5206 ArrayList table = GetTable(tableIx);
5207 elem.Row = (uint)table.Count + 1;
5211 internal uint TableIndex(MDTable tableIx)
5213 if (metaDataTables[(int)tableIx] == null) return 1;
5214 return (uint)metaDataTables[(int)tableIx].Count+1;
5217 internal uint AddCode(CILInstructions byteCode)
5219 byteCodes.Add(byteCode);
5220 uint offset = codeSize + codeStart;
5221 codeSize += byteCode.GetCodeSize();
5225 internal void SetEntryPoint(MetaDataElement ep)
5230 internal uint AddResource(byte[] resBytes)
5232 if (resources == null) resources = new ArrayList ();
5233 resources.Add (resBytes);
5234 uint offset = resourcesSize;
5235 resourcesSize += (uint)resBytes.Length + 4;
5239 internal void AddData(DataConstant cVal)
5241 file.AddInitData(cVal);
5244 internal static void CompressNum(uint val, MemoryStream sig)
5247 sig.WriteByte((byte)val);
5248 } else if (val <= 0x3FFF) {
5249 byte b1 = (byte)((val >> 8) | 0x80);
5250 byte b2 = (byte)(val & FileImage.iByteMask[0]);
5254 byte b1 = (byte)((val >> 24) | 0xC0);
5255 byte b2 = (byte)((val & FileImage.iByteMask[2]) >> 16);
5256 byte b3 = (byte)((val & FileImage.iByteMask[1]) >> 8);;
5257 byte b4 = (byte)(val & FileImage.iByteMask[0]);
5265 internal uint CodeSize()
5267 return codeSize + byteCodePadding;
5270 internal uint GetResourcesSize()
5272 return resourcesSize;
5275 internal uint StringsIndexSize()
5277 if (largeStrings) return 4;
5281 internal uint GUIDIndexSize()
5283 if (largeGUID) return 4;
5287 internal uint USIndexSize()
5289 if (largeUS) return 4;
5293 internal uint BlobIndexSize()
5295 if (largeBlob) return 4;
5299 internal uint CodedIndexSize(CIx code)
5301 if (lgeCIx[(uint)code]) return 4;
5305 internal uint TableIndexSize(MDTable tabIx)
5307 if (largeIx[(uint)tabIx]) return 4;
5311 private void SetIndexSizes()
5313 for (int i=0; i < numMetaDataTables; i++) {
5314 if (metaDataTables[i] == null)
5317 uint count = (uint)metaDataTables[i].Count;
5318 if (count > maxSmlIxSize)
5321 MDTable tabIx = (MDTable)i;
5322 if (count > max5BitSmlIx) {
5323 lgeCIx[(int)CIx.HasCustomAttr] = true;
5325 if (count > max3BitSmlIx) {
5326 if ((tabIx == MDTable.TypeRef) || (tabIx == MDTable.ModuleRef) || (tabIx == MDTable.Method) || (tabIx == MDTable.TypeSpec) || (tabIx == MDTable.Field))
5327 lgeCIx[(int)CIx.CustomAttributeType] = true;
5328 if ((tabIx == MDTable.Method) || (tabIx == MDTable.MemberRef))
5329 lgeCIx[(int)CIx.MemberRefParent] = true;
5331 if (count > max2BitSmlIx) {
5332 if ((tabIx == MDTable.Field) || (tabIx == MDTable.Param) || (tabIx == MDTable.Property))
5333 lgeCIx[(int)CIx.HasConst] = true;
5334 if ((tabIx == MDTable.TypeDef) || (tabIx == MDTable.TypeRef) || (tabIx == MDTable.TypeSpec))
5335 lgeCIx[(int)CIx.TypeDefOrRef] = true;
5336 if ((tabIx == MDTable.TypeDef) || (tabIx == MDTable.Method) || (tabIx == MDTable.Assembly))
5337 lgeCIx[(int)CIx.HasDeclSecurity] = true;
5338 if ((tabIx == MDTable.File) || (tabIx == MDTable.AssemblyRef) || (tabIx == MDTable.ExportedType))
5339 lgeCIx[(int)CIx.Implementation] = true;
5340 if ((tabIx == MDTable.Module) || (tabIx == MDTable.ModuleRef) || (tabIx == MDTable.AssemblyRef) || (tabIx == MDTable.TypeRef))
5341 lgeCIx[(int)CIx.ResolutionScope] = true;
5343 if (count > max1BitSmlIx) {
5344 if ((tabIx == MDTable.Field) || (tabIx == MDTable.Param))
5345 lgeCIx[(int)CIx.HasFieldMarshal] = true;
5346 if ((tabIx == MDTable.Event) || (tabIx == MDTable.Property))
5347 lgeCIx[(int)CIx.HasSemantics] = true;
5348 if ((tabIx == MDTable.Method) || (tabIx == MDTable.MemberRef))
5349 lgeCIx[(int)CIx.MethodDefOrRef] = true;
5350 if ((tabIx == MDTable.Field) || (tabIx == MDTable.Method))
5351 lgeCIx[(int)CIx.MemberForwarded] = true;
5352 if ((tabIx == MDTable.TypeDef) || (tabIx == MDTable.Method))
5353 lgeCIx[(int)CIx.TypeOrMethodDef] = true;
5358 private void SetStreamOffsets()
5360 uint sizeOfHeaders = StreamHeaderSize + (uint)tildeName.Length;
5361 for (int i=1; i < numStreams; i++) {
5362 sizeOfHeaders += streams[i].headerSize();
5364 metaDataSize = MetaDataHeaderSize + sizeOfHeaders;
5365 tildeStart = metaDataSize;
5366 metaDataSize += tildeTide + tildePadding;
5367 for (int i=1; i < numStreams; i++) {
5368 streams[i].Start = metaDataSize;
5369 metaDataSize += streams[i].Size();
5370 streams[i].WriteDetails();
5374 internal void CalcTildeStreamSize()
5377 //tilde.SetIndexSizes(strings.LargeIx(),us.LargeIx(),guid.LargeIx(),blob.LargeIx());
5378 tildeTide = TildeHeaderSize;
5379 tildeTide += 4 * numTables;
5380 //Console.WriteLine("Tilde header + sizes = " + tildeTide);
5381 for (int i=0; i < numMetaDataTables; i++) {
5382 if (metaDataTables[i] != null) {
5383 ArrayList table = metaDataTables[i];
5384 // Console.WriteLine("Meta data table " + i + " at offset " + tildeTide);
5385 tildeTide += (uint)table.Count * ((MetaDataElement)table[0]).Size(this);
5386 // Console.WriteLine("Metadata table " + i + " has size " + table.Count);
5387 // Console.WriteLine("tildeTide = " + tildeTide);
5390 if ((tildeTide % 4) != 0) tildePadding = 4 - (tildeTide % 4);
5391 //Console.WriteLine("tildePadding = " + tildePadding);
5394 internal void WriteTildeStream(FileImage output)
5396 output.Seek(0,SeekOrigin.Current);
5397 output.Write((uint)0); // Reserved
5398 output.Write((byte)2); // MajorVersion
5399 output.Write((byte)0); // MinorVersion
5400 output.Write(heapSizes);
5401 output.Write((byte)1); // Reserved
5402 output.Write(valid);
5403 output.Write(sorted);
5405 for (int i=0; i < numMetaDataTables; i++) {
5406 if (metaDataTables[i] != null) {
5407 uint count = (uint)metaDataTables[i].Count;
5408 output.Write(count);
5412 output.Seek(0,SeekOrigin.Current);
5413 // Console.WriteLine("Starting metaData tables at " + tabStart);
5414 for (int i=0; i < numMetaDataTables; i++) {
5415 if (metaDataTables[i] != null) {
5416 // Console.WriteLine("Starting metaData table " + i + " at " + (output.Seek(0,SeekOrigin.Current) - startTilde));
5417 ArrayList table = metaDataTables[i];
5418 for (int j=0; j < table.Count; j++) {
5419 ((MetaDataElement)table[j]).Write(output);
5423 // Console.WriteLine("Writing padding at " + output.Seek(0,SeekOrigin.Current));
5424 for (int i=0; i < tildePadding; i++) output.Write((byte)0);
5427 private void BuildTable(ArrayList table)
5429 if (table == null) return;
5430 for (int j=0; j < table.Count; j++) {
5431 ((MetaDataElement)table[j]).BuildTables(this);
5435 private void SortTable (ArrayList mTable)
5437 if (mTable == null) return;
5439 for (int i=0; i < mTable.Count; i++) {
5440 ((MetaDataElement)mTable[i]).Row = (uint)i+1;
5444 internal void BuildMetaData(uint codeStartOffset)
5446 codeStart = codeStartOffset;
5447 BuildTable(metaDataTables[(int)MDTable.TypeDef]);
5448 BuildTable(metaDataTables[(int)MDTable.TypeSpec]);
5449 BuildTable(metaDataTables[(int)MDTable.MemberRef]);
5450 BuildTable(metaDataTables[(int)MDTable.GenericParam]);
5451 BuildTable(metaDataTables[(int)MDTable.MethodSpec]);
5452 BuildTable(metaDataTables[(int)MDTable.GenericParamConstraint]);
5453 BuildTable(metaDataTables[(int)MDTable.ManifestResource]);
5455 if (cattr_list != null) {
5456 foreach (CustomAttribute cattr in cattr_list)
5457 cattr.BuildTables (this);
5460 if (declsec_list != null) {
5461 foreach (BaseDeclSecurity decl_sec in declsec_list)
5462 decl_sec.BuildTables (this);
5465 /* for (int i=0; i < metaDataTables.Length; i++) {
5466 ArrayList table = metaDataTables[i];
5467 if (table != null) {
5468 for (int j=0; j < table.Count; j++) {
5469 ((MetaDataElement)table[j]).BuildTables(this);
5476 for (int i=1; i < numStreams; i++) {
5477 streams[i].EndStream();
5479 CalcTildeStreamSize();
5481 byteCodePadding = NumToAlign(codeSize,4);
5482 if (entryPoint != null) file.SetEntryPoint(entryPoint.Token());
5484 // Check ordering of specific tables
5485 // Constant, CustomAttribute, FieldMarshal, DeclSecurity, MethodSemantics
5486 // ImplMap, GenericParam
5487 // Need to load GenericParamConstraint AFTER GenericParam table in correct order
5489 // InterfaceImpl, ClassLayout, FieldLayout, MethodImpl, FieldRVA, NestedClass
5490 // will _ALWAYS_ be in the correct order as embedded in BuildMDTables
5492 SortTable(metaDataTables[(int)MDTable.Constant]);
5493 SortTable(metaDataTables[(int)MDTable.FieldMarshal]);
5494 SortTable(metaDataTables[(int)MDTable.DeclSecurity]);
5495 SortTable(metaDataTables[(int)MDTable.MethodSemantics]);
5496 SortTable(metaDataTables[(int)MDTable.ImplMap]);
5497 if (metaDataTables[(int)MDTable.GenericParam] != null) {
5498 SortTable(metaDataTables[(int)MDTable.GenericParam]);
5499 // Now add GenericParamConstraints
5500 /*for (int i=0; i < metaDataTables[(int)MDTable.GenericParam].Count; i++) {
5501 ((GenericParameter)metaDataTables[(int)MDTable.GenericParam][i]).AddConstraints(this);
5504 SortTable(metaDataTables[(int)MDTable.GenericParamConstraint]);
5505 SortTable(metaDataTables[(int)MDTable.InterfaceImpl]);
5506 SortTable(metaDataTables[(int)MDTable.CustomAttribute]);
5510 internal void WriteByteCodes(FileImage output)
5512 for (int i=0; i < byteCodes.Count; i++) {
5513 ((CILInstructions)byteCodes[i]).Write(output);
5515 for (int i=0; i < byteCodePadding; i++) {
5516 output.Write((byte)0);
5520 internal void WriteResources (FileImage output)
5522 if (resources == null) return;
5523 for (int i = 0; i < resources.Count; i ++) {
5524 byte [] resBytes = (byte []) resources [i];
5525 output.Write ((uint) resBytes.Length);
5526 output.Write (resBytes);
5530 internal void WriteMetaData(FileImage output)
5532 this.output = output;
5533 mdStart = output.Seek(0,SeekOrigin.Current);
5534 // Console.WriteLine("Writing metaData at " + Hex.Long(mdStart));
5535 output.Write(MetaDataSignature);
5536 output.Write((short)1); // Major Version
5537 output.Write((short)1); // Minor Version ECMA = 0, PEFiles = 1
5538 output.Write(0); // Reserved
5539 output.Write(version.Length);
5540 output.Write(version.ToCharArray()); // version string is already zero padded
5541 output.Write((short)0);
5542 output.Write((ushort)numStreams);
5543 // write tilde header
5544 output.Write(tildeStart);
5545 output.Write(tildeTide + tildePadding);
5546 output.Write(tildeName);
5547 for (int i=1; i < numStreams; i++) streams[i].WriteHeader(output);
5548 // Console.WriteLine("Writing tilde stream at " + output.Seek(0,SeekOrigin.Current) + " = " + tildeStart);
5549 WriteTildeStream(output);
5550 for (int i=1; i < numStreams; i++) streams[i].Write(output);
5551 // Console.WriteLine("Finished Writing metaData at " + output.Seek(0,SeekOrigin.Current));
5554 internal bool LargeStringsIndex() { return strings.LargeIx(); }
5555 internal bool LargeGUIDIndex() { return guid.LargeIx(); }
5556 internal bool LargeUSIndex() { return us.LargeIx(); }
5557 internal bool LargeBlobIndex() { return blob.LargeIx(); }
5559 internal bool LargeIx(MDTable tabIx) { return largeIx[(uint)tabIx]; }
5562 private uint NumToAlign(uint val, uint alignVal)
5564 if ((val % alignVal) == 0) return 0;
5565 return alignVal - (val % alignVal);
5568 internal void WriteCodedIndex(CIx code, MetaDataElement elem, FileImage output)
5572 ix = (elem.Row << CIxShiftMap[(uint)code]) | elem.GetCodedIx(code);
5573 // Console.WriteLine("coded index = " + ix + " row = " + elem.Row);
5575 // Console.WriteLine("elem for coded index is null");
5577 if (lgeCIx[(uint)code])
5580 output.Write((ushort)ix);
5585 /**************************************************************************/
5587 /// Stream in the Meta Data (#Strings, #US, #Blob and #GUID)
5590 internal class MetaDataStream : BinaryWriter {
5592 private static readonly uint StreamHeaderSize = 8;
5593 private static uint maxSmlIxSize = 0xFFFF;
5595 private uint start = 0;
5596 uint size = 0, tide = 1;
5597 bool largeIx = false;
5600 Hashtable htable = new Hashtable();
5601 Hashtable btable = new Hashtable (new ByteArrayHashCodeProvider (), new ByteArrayComparer ());
5603 internal MetaDataStream(char[] name, bool addInitByte) : base(new MemoryStream())
5605 if (addInitByte) { Write((byte)0); size = 1; }
5607 sizeOfHeader = StreamHeaderSize + (uint)name.Length;
5610 internal MetaDataStream(char[] name, System.Text.Encoding enc, bool addInitByte) : base(new MemoryStream(),enc)
5612 if (addInitByte) { Write((byte)0); size = 1; }
5614 sizeOfHeader = StreamHeaderSize + (uint)name.Length;
5618 get { return start; }
5619 set { start = value; }
5622 internal uint headerSize()
5624 // Console.WriteLine(name + " stream has headersize of " + sizeOfHeader);
5625 return sizeOfHeader;
5628 internal void SetSize(uint siz)
5633 internal uint Size()
5638 internal bool LargeIx()
5643 internal void WriteDetails()
5645 // Console.WriteLine(name + " - size = " + size);
5648 internal uint Add(string str, bool prependSize)
5650 Object val = htable[str];
5654 htable[str] = index;
5655 char[] arr = str.ToCharArray();
5656 if (prependSize) CompressNum((uint)arr.Length*2+1);
5659 size = (uint)Seek(0,SeekOrigin.Current);
5665 internal uint Add (byte[] str, bool prependSize)
5667 Object val = btable [str];
5671 btable [str] = index;
5672 if (prependSize) CompressNum ((uint) str.Length);
5674 size = (uint) Seek (0, SeekOrigin.Current);
5682 internal uint Add(Guid guid, bool prependSize)
5684 byte [] b = guid.ToByteArray ();
5685 if (prependSize) CompressNum ((uint) b.Length);
5686 Write(guid.ToByteArray());
5687 size =(uint)Seek(0,SeekOrigin.Current);
5691 internal uint Add(byte[] blob)
5694 CompressNum((uint)blob.Length);
5696 size = (uint)Seek(0,SeekOrigin.Current);
5700 internal uint Add(byte val, bool prependSize)
5703 if (prependSize) CompressNum (1);
5705 size = (uint)Seek(0,SeekOrigin.Current);
5709 internal uint Add(sbyte val, bool prependSize)
5712 if (prependSize) CompressNum (1);
5714 size = (uint)Seek(0,SeekOrigin.Current);
5718 internal uint Add(ushort val, bool prependSize)
5721 if (prependSize) CompressNum (2);
5723 size = (uint)Seek(0,SeekOrigin.Current);
5727 internal uint Add(short val, bool prependSize)
5730 if (prependSize) CompressNum (2);
5732 size = (uint)Seek(0,SeekOrigin.Current);
5736 internal uint Add(uint val, bool prependSize)
5739 if (prependSize) CompressNum (4);
5741 size = (uint)Seek(0,SeekOrigin.Current);
5745 internal uint Add(int val, bool prependSize)
5748 if (prependSize) CompressNum (4);
5750 size = (uint)Seek(0,SeekOrigin.Current);
5754 internal uint Add(ulong val, bool prependSize)
5757 if (prependSize) CompressNum (8);
5759 size = (uint)Seek(0,SeekOrigin.Current);
5763 internal uint Add(long val, bool prependSize)
5766 if (prependSize) CompressNum (8);
5768 size = (uint)Seek(0,SeekOrigin.Current);
5772 internal uint Add(float val, bool prependSize)
5775 if (prependSize) CompressNum (4);
5777 size = (uint)Seek(0,SeekOrigin.Current);
5781 internal uint Add(double val, bool prependSize)
5784 if (prependSize) CompressNum (8);
5786 size = (uint)Seek(0,SeekOrigin.Current);
5790 private void CompressNum(uint val)
5794 } else if (val < 0x3FFF) {
5795 byte b1 = (byte)((val >> 8) | 0x80);
5796 byte b2 = (byte)(val & FileImage.iByteMask[0]);
5800 byte b1 = (byte)((val >> 24) | 0xC0);
5801 byte b2 = (byte)((val & FileImage.iByteMask[2]) >> 16);
5802 byte b3 = (byte)((val & FileImage.iByteMask[1]) >> 8);;
5803 byte b4 = (byte)(val & FileImage.iByteMask[0]);
5811 private void QuadAlign()
5813 if ((size % 4) != 0) {
5814 uint pad = 4 - (size % 4);
5816 for (int i=0; i < pad; i++) {
5822 internal void EndStream()
5825 if (size > maxSmlIxSize) {
5830 internal void WriteHeader(BinaryWriter output)
5832 output.Write(start);
5837 internal virtual void Write(BinaryWriter output)
5839 // Console.WriteLine("Writing " + name + " stream at " + output.Seek(0,SeekOrigin.Current) + " = " + start);
5840 MemoryStream str = (MemoryStream)BaseStream;
5841 output.Write(str.ToArray());
5846 /**************************************************************************/
5847 class ByteArrayComparer : IComparer {
5849 public int Compare (object x, object y)
5851 byte [] a = (byte []) x;
5852 byte [] b = (byte []) y;
5855 if (b.Length != len)
5858 for (int i = 0; i < len; ++i)
5865 class ByteArrayHashCodeProvider : IHashCodeProvider {
5867 public int GetHashCode (Object key)
5869 byte [] arr = (byte []) key;
5870 int len = arr.Length;
5873 for (int i = 0; i < len; ++i)
5874 h = (h << 5) - h + arr [i];