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 ms = new MemoryStream ();
461 var sc = c as StringConst;
463 string value = sc.val;
465 throw new NotImplementedException ();
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 var ac = c as ArrayConstant;
477 var bw = new BinaryWriter (ms);
478 bw.Write (ac.ExplicitSize.Value);
481 return ms.ToArray ();
484 throw new NotImplementedException (c.GetType ().ToString ());
487 internal CustomAttribute(MetaDataElement paren, Method constrType,
491 tabIx = MDTable.CustomAttribute;
495 internal override uint SortKey()
497 return (parent.Row << MetaData.CIxShiftMap[(uint)CIx.HasCustomAttr])
498 | parent.GetCodedIx(CIx.HasCustomAttr);
501 public void AddFieldOrProp(string name, Constant val)
504 names = new ArrayList();
505 vals = new ArrayList();
511 internal sealed override void BuildTables(MetaData md)
513 md.AddToTable(MDTable.CustomAttribute, this);
514 if (byteVal == null) {
519 BinaryWriter bw = new BinaryWriter(new MemoryStream());
521 MemoryStream str = (MemoryStream)bw.BaseStream;
522 valIx = md.AddToBlobHeap(str.ToArray());
525 internal sealed override uint Size(MetaData md)
527 return md.CodedIndexSize(CIx.HasCustomAttr) + md.CodedIndexSize(CIx.CustomAttributeType) + md.BlobIndexSize();
530 internal sealed override void Write(FileImage output)
532 output.WriteCodedIndex(CIx.HasCustomAttr,parent);
533 output.WriteCodedIndex(CIx.CustomAttributeType,type);
534 output.BlobIndex(valIx);
539 /**************************************************************************/
541 /// Descriptor for security permissions for a class or a method
544 public abstract class BaseDeclSecurity : MetaDataElement {
547 MetaDataElement parent;
550 internal BaseDeclSecurity(MetaDataElement paren, ushort act)
554 tabIx = MDTable.DeclSecurity;
557 internal override uint SortKey()
559 return (parent.Row << MetaData.CIxShiftMap[(uint)CIx.HasDeclSecurity])
560 | parent.GetCodedIx(CIx.HasDeclSecurity);
563 internal sealed override uint Size(MetaData md)
565 return 2 + md.CodedIndexSize(CIx.HasDeclSecurity) + md.BlobIndexSize();
568 internal sealed override void BuildTables(MetaData md)
572 BinaryWriter bw = new BinaryWriter (new MemoryStream ());
573 md.AddToTable (MDTable.DeclSecurity, this);
574 MemoryStream str = (MemoryStream)bw.BaseStream;
576 permissionIx = md.AddToBlobHeap(str.ToArray());
581 internal abstract void WriteSig (BinaryWriter bw);
583 internal sealed override void Write(FileImage output)
585 output.Write(action);
586 output.WriteCodedIndex(CIx.HasDeclSecurity,parent);
587 output.BlobIndex(permissionIx);
592 public class DeclSecurity : BaseDeclSecurity {
596 internal DeclSecurity(MetaDataElement paren, ushort act, byte [] val)
602 internal override void WriteSig (BinaryWriter bw)
609 public class DeclSecurity_20 : BaseDeclSecurity {
613 internal DeclSecurity_20 (MetaDataElement paren, ushort act, PermissionSet ps)
619 internal override void WriteSig (BinaryWriter bw)
625 public class PermissionMember {
627 MemberTypes member_type;
632 public PermissionMember (MemberTypes member_type, PEAPI.Type type, string name, object value)
634 this.member_type = member_type;
640 public void Write (BinaryWriter bw)
644 if (member_type == MemberTypes.Field)
645 bw.Write ((byte) 0x53);
648 bw.Write ((byte) 0x54);
650 if (type is PrimitiveType) {
651 bw.Write (type.GetTypeIndex ());
654 bw.Write ((byte) 0x55); //ENUM
656 b = Encoding.UTF8.GetBytes (((ClassRef) type).TypeName ());
657 MetaData.CompressNum ((uint) b.Length, (MemoryStream) bw.BaseStream);
661 b = Encoding.UTF8.GetBytes (name);
662 MetaData.CompressNum ((uint) b.Length, (MemoryStream) bw.BaseStream);
665 ((Constant) value).Write (bw);
670 public class Permission
678 public Permission (PEAPI.Type type, string name)
684 public void AddMember (PEAPI.PermissionMember member)
687 members = new ArrayList ();
689 members.Add (member);
692 public void Write (BinaryWriter bw)
694 byte [] b = Encoding.UTF8.GetBytes (name);
695 MetaData.CompressNum ((uint) b.Length, (MemoryStream) bw.BaseStream);
698 BinaryWriter perm_writer = new BinaryWriter (new MemoryStream (), Encoding.Unicode);
699 MemoryStream str = (MemoryStream) perm_writer.BaseStream;
701 MetaData.CompressNum ((uint) members.Count, str);//number of params
702 foreach (PermissionMember member in members)
703 member.Write (perm_writer);
705 bw.Write ((byte) str.Length); //(optional) parameters length
706 bw.Write (str.ToArray ());
710 public class PermissionSet
712 PEAPI.SecurityAction sec_action;
713 ArrayList permissions;
715 public PermissionSet (PEAPI.SecurityAction sec_action)
717 this.sec_action = sec_action;
720 public void AddPermission (PEAPI.Permission perm)
722 if (permissions == null)
723 permissions = new ArrayList ();
725 permissions.Add (perm);
728 public void Write (BinaryWriter bw)
730 bw.Write ((byte) 0x2e);
731 MetaData.CompressNum ((uint) permissions.Count, (MemoryStream) bw.BaseStream);
733 foreach (Permission perm in permissions)
739 /**************************************************************************/
741 /// Descriptor for layout information for a field
744 public class FieldLayout : MetaDataElement {
749 internal FieldLayout(Field field, uint offset)
752 this.offset = offset;
753 tabIx = MDTable.FieldLayout;
756 internal sealed override uint Size(MetaData md)
758 return 4 + md.TableIndexSize(MDTable.Field);
761 internal sealed override void Write(FileImage output)
763 output.Write(offset);
764 output.WriteIndex(MDTable.Field,field.Row);
769 /*****************************************************************************/
771 /// Marshalling information for a field or param
773 public class FieldMarshal : MetaDataElement {
775 MetaDataElement field;
779 internal FieldMarshal(MetaDataElement field, NativeType nType)
783 tabIx = MDTable.FieldMarshal;
786 internal override uint SortKey()
788 return (field.Row << MetaData.CIxShiftMap[(uint)CIx.HasFieldMarshal])
789 | field.GetCodedIx(CIx.HasFieldMarshal);
792 internal sealed override void BuildTables(MetaData md)
795 ntIx = md.AddToBlobHeap(nt.ToBlob());
799 internal sealed override uint Size(MetaData md)
801 return md.CodedIndexSize(CIx.HasFieldMarshal) + md.BlobIndexSize();
804 internal sealed override void Write(FileImage output)
806 output.WriteCodedIndex(CIx.HasFieldMarshal,field);
807 output.BlobIndex(ntIx);
812 /**************************************************************************/
814 /// Descriptor for the address of a field's value in the PE file
816 public class FieldRVA : MetaDataElement {
821 internal FieldRVA(Field field, DataConstant data)
825 tabIx = MDTable.FieldRVA;
828 internal sealed override void BuildTables(MetaData md)
835 internal sealed override uint Size(MetaData md)
837 return 4 + md.TableIndexSize(MDTable.Field);
840 internal sealed override void Write(FileImage output)
842 output.WriteDataRVA(data.DataOffset);
843 output.WriteIndex(MDTable.Field,field.Row);
848 /**************************************************************************/
850 /// Descriptor for a file referenced in THIS assembly/module (.file)
852 public class FileRef : MetaDataElement {
854 private static readonly uint NoMetaData = 0x1;
855 uint nameIx = 0, hashIx = 0;
857 protected string name;
859 internal FileRef(string name, byte[] hashBytes, bool metaData,
860 bool entryPoint, MetaData md) {
861 if (!metaData) flags = NoMetaData;
862 if (entryPoint) md.SetEntryPoint(this);
864 nameIx = md.AddToStringsHeap(name);
865 hashIx = md.AddToBlobHeap(hashBytes);
866 tabIx = MDTable.File;
869 internal FileRef(uint nameIx, byte[] hashBytes, bool metaData,
870 bool entryPoint, MetaData md) {
871 if (!metaData) flags = NoMetaData;
872 if (entryPoint) md.SetEntryPoint(this);
873 this.nameIx = nameIx;
874 hashIx = md.AddToBlobHeap(hashBytes);
875 tabIx = MDTable.File;
878 internal sealed override uint Size(MetaData md)
880 return 4 + md.StringsIndexSize() + md.BlobIndexSize();
883 internal sealed override void BuildTables(MetaData md)
885 md.AddToTable(MDTable.File,this);
888 internal sealed override void Write(FileImage output)
891 output.StringsIndex(nameIx);
892 output.BlobIndex(hashIx);
895 internal sealed override uint GetCodedIx(CIx code)
898 case (CIx.HasCustomAttr) : return 16;
899 case (CIx.Implementation) : return 0;
905 /**************************************************************************/
907 /// Descriptor for pinvoke information for a method NOT YET IMPLEMENTED
909 public class ImplMap : MetaDataElement {
911 private static readonly ushort NoMangle = 0x01;
916 ModuleRef importScope;
918 internal ImplMap(ushort flag, Method implMeth, string iName, ModuleRef mScope)
923 importScope = mScope;
924 tabIx = MDTable.ImplMap;
925 if (iName == null) flags |= NoMangle;
926 //throw(new NotYetImplementedException("PInvoke "));
929 internal override uint SortKey()
931 return (meth.Row << MetaData.CIxShiftMap[(uint)CIx.MemberForwarded])
932 | meth.GetCodedIx(CIx.MemberForwarded);
935 internal sealed override void BuildTables(MetaData md)
938 iNameIx = md.AddToStringsHeap(importName);
942 internal sealed override uint Size(MetaData md)
944 return 2+ md.CodedIndexSize(CIx.MemberForwarded) +
945 md.StringsIndexSize() + md.TableIndexSize(MDTable.ModuleRef);
948 internal sealed override void Write(FileImage output)
951 output.WriteCodedIndex(CIx.MemberForwarded,meth);
952 output.StringsIndex(iNameIx);
953 output.WriteIndex(MDTable.ModuleRef,importScope.Row);
958 /**************************************************************************/
960 public class GenericParameter : MetaDataElement {
962 MetaDataElement owner;
967 GenericParamAttributes attr;
969 internal GenericParameter (ClassDef owner, MetaData metadata,
970 short index, string name, GenericParamAttributes attr) : this (owner, metadata, index, name, attr, true)
974 internal GenericParameter (MethodDef owner, MetaData metadata,
975 short index, string name, GenericParamAttributes attr) : this (owner, metadata, index, name, attr, true)
979 private GenericParameter (MetaDataElement owner, MetaData metadata,
980 short index, string name, GenericParamAttributes attr, bool nadda) {
982 this.metadata = metadata;
984 tabIx = MDTable.GenericParam;
989 internal override uint SortKey()
991 return (owner.Row << MetaData.CIxShiftMap[(uint)CIx.TypeOrMethodDef])
992 | owner.GetCodedIx(CIx.TypeOrMethodDef);
995 internal override uint SortKey2 ()
1000 public void AddConstraint (Type constraint)
1002 metadata.AddToTable (MDTable.GenericParamConstraint,
1003 new GenericParamConstraint (this, constraint));
1006 internal sealed override uint Size(MetaData md)
1009 md.CodedIndexSize(CIx.TypeOrMethodDef) +
1010 md.StringsIndexSize ());
1013 internal sealed override void BuildTables(MetaData md)
1016 nameIx = md.AddToStringsHeap(name);
1020 internal sealed override void Write(FileImage output)
1022 output.Write ((short) index);
1023 output.Write ((short) attr);
1024 output.WriteCodedIndex(CIx.TypeOrMethodDef, owner);
1025 output.StringsIndex (nameIx);
1028 internal sealed override uint GetCodedIx(CIx code)
1031 case (CIx.HasCustomAttr) : return 19;
1038 internal class GenericParamConstraint : MetaDataElement {
1040 GenericParameter param;
1043 public GenericParamConstraint (GenericParameter param, Type type)
1047 tabIx = MDTable.GenericParamConstraint;
1050 internal override uint SortKey()
1055 internal sealed override uint Size(MetaData md)
1057 return (uint) (md.TableIndexSize(MDTable.GenericParam) +
1058 md.CodedIndexSize(CIx.TypeDefOrRef));
1061 internal sealed override void Write(FileImage output)
1063 output.WriteIndex(MDTable.GenericParam, param.Row);
1064 output.WriteCodedIndex(CIx.TypeDefOrRef, type);
1069 internal class MethodSpec : Method {
1072 GenericMethodSig g_sig;
1075 internal MethodSpec (Method meth, GenericMethodSig g_sig) : base ("")
1079 tabIx = MDTable.MethodSpec;
1082 internal override uint GetSigIx (MetaData md)
1084 throw new Exception ("Should not be used.");
1087 public override void AddCallConv (CallConv cconv)
1089 throw new Exception ("Should not be used.");
1092 internal sealed override void BuildTables (MetaData md)
1095 sidx = g_sig.GetSigIx (md);
1099 internal sealed override uint Size (MetaData md)
1101 return (uint) (md.CodedIndexSize(CIx.MethodDefOrRef) +
1102 md.BlobIndexSize ());
1105 internal sealed override void Write (FileImage output)
1107 output.WriteCodedIndex (CIx.MethodDefOrRef, meth);
1108 output.BlobIndex (sidx);
1111 internal sealed override void TypeSig (MemoryStream sig)
1113 throw new Exception ("Should not be used.");
1117 /**************************************************************************/
1119 /// Descriptor for interface implemented by a class
1121 public class InterfaceImpl: MetaDataElement {
1126 internal InterfaceImpl(ClassDef theClass, Class theInterface)
1128 this.theClass = theClass;
1129 this.theInterface = theInterface;
1130 tabIx = MDTable.InterfaceImpl;
1133 internal sealed override uint Size(MetaData md)
1135 return md.TableIndexSize(MDTable.TypeDef) +
1136 md.CodedIndexSize(CIx.TypeDefOrRef);
1139 internal sealed override void Write(FileImage output)
1141 output.WriteIndex(MDTable.TypeDef,theClass.Row);
1142 output.WriteCodedIndex(CIx.TypeDefOrRef,theInterface);
1145 internal sealed override uint GetCodedIx(CIx code) { return 5; }
1147 internal override uint SortKey ()
1149 return (theClass.Row << MetaData.CIxShiftMap[(uint)CIx.TypeDefOrRef])
1150 | theClass.GetCodedIx (CIx.TypeDefOrRef);
1155 /**************************************************************************/
1157 /// Descriptor for resources used in this PE file
1160 public class ManifestResource : MetaDataElement {
1162 public static readonly uint PublicResource = 0x1;
1163 public static readonly uint PrivateResource = 0x2;
1166 MetaDataElement rRef;
1170 byte [] resourceBytes;
1172 public ManifestResource (string name, byte[] resBytes, uint flags)
1174 InitResource (name, flags);
1175 this.resourceBytes = resBytes;
1178 public ManifestResource(string name, uint flags, FileRef fileRef)
1180 InitResource (name, flags);
1184 public ManifestResource(string name, uint flags, FileRef fileRef,
1186 InitResource (name, flags);
1188 fileOffset = fileIx;
1191 public ManifestResource(string name, uint flags, AssemblyRef assemRef)
1193 InitResource (name, flags);
1197 internal ManifestResource (ManifestResource mres)
1199 mrName = mres.mrName;
1202 fileOffset = mres.fileOffset;
1203 resourceBytes = mres.resourceBytes;
1206 private void InitResource (string name, uint flags)
1210 tabIx = MDTable.ManifestResource;
1213 internal sealed override void BuildTables(MetaData md)
1216 md.AddToTable (MDTable.ManifestResource, this);
1217 nameIx = md.AddToStringsHeap(mrName);
1218 if (resourceBytes != null) {
1220 throw new PEFileException ("Manifest Resource has byte value and file reference");
1221 fileOffset = md.AddResource(resourceBytes);
1224 throw new PEFileException ("Manifest Resource has no implementation or value");
1225 rRef.BuildTables (md);
1231 internal sealed override uint Size(MetaData md)
1233 return 8 + md.StringsIndexSize() +
1234 md.CodedIndexSize(CIx.Implementation);
1237 internal sealed override void Write(FileImage output)
1239 output.Write(fileOffset);
1240 output.Write(flags);
1241 output.StringsIndex(nameIx);
1242 output.WriteCodedIndex(CIx.Implementation,rRef);
1245 internal sealed override uint GetCodedIx(CIx code) { return 18; }
1247 public string Name {
1248 get { return mrName; }
1249 set { mrName = value; }
1253 /**************************************************************************/
1255 /// Base class for elements in the PropertyMap, EventMap and
1256 /// NestedClass MetaData tables
1258 public class MapElem : MetaDataElement {
1264 internal MapElem(ClassDef par, uint elIx, MDTable elemTab)
1268 elemTable = elemTab;
1271 internal sealed override uint Size(MetaData md)
1273 return md.TableIndexSize(MDTable.TypeDef) + md.TableIndexSize(elemTable);
1276 internal sealed override void Write(FileImage output)
1278 output.WriteIndex(MDTable.TypeDef,parent.Row);
1279 output.WriteIndex(elemTable,elemIx);
1283 /**************************************************************************/
1285 /// Descriptor for an overriding method (.override)
1287 public class MethodImpl : MetaDataElement {
1290 Method header, body;
1292 internal MethodImpl(ClassDef par, Method decl, Method bod)
1297 tabIx = MDTable.MethodImpl;
1300 internal sealed override uint Size(MetaData md)
1302 return md.TableIndexSize(MDTable.TypeDef) + 2 * md.CodedIndexSize(CIx.MethodDefOrRef);
1305 internal sealed override void Write(FileImage output)
1307 output.WriteIndex(MDTable.TypeDef,parent.Row);
1308 output.WriteCodedIndex(CIx.MethodDefOrRef,body);
1309 output.WriteCodedIndex(CIx.MethodDefOrRef,header);
1314 /**************************************************************************/
1316 /// Descriptor for Property and Event methods
1318 public class MethodSemantics : MetaDataElement {
1320 Feature.MethodType type;
1322 Feature eventOrProp;
1324 internal MethodSemantics(Feature.MethodType mType, MethodDef method, Feature feature)
1328 eventOrProp = feature;
1329 tabIx = MDTable.MethodSemantics;
1332 internal override uint SortKey()
1334 return (eventOrProp.Row << MetaData.CIxShiftMap [(uint)CIx.HasSemantics])
1335 | eventOrProp.GetCodedIx (CIx.HasSemantics);
1338 internal sealed override uint Size(MetaData md)
1340 return 2 + md.TableIndexSize(MDTable.Method) + md.CodedIndexSize(CIx.HasSemantics);
1343 internal sealed override void Write(FileImage output)
1345 output.Write((ushort)type);
1346 output.WriteIndex(MDTable.Method,meth.Row);
1347 output.WriteCodedIndex(CIx.HasSemantics,eventOrProp);
1352 /**************************************************************************/
1354 /// Descriptor for a parameter of a method defined in this assembly/module
1356 public class Param : MetaDataElement {
1361 internal ushort seqNo = 0;
1363 ConstantElem defaultVal;
1365 FieldMarshal marshalInfo;
1368 /// Create a new parameter for a method
1370 /// <param name="mode">param mode (in, out, opt)</param>
1371 /// <param name="parName">parameter name</param>
1372 /// <param name="parType">parameter type</param>
1373 public Param(ParamAttr mode, string parName, Type parType)
1377 parMode = (ushort)mode;
1378 tabIx = MDTable.Param;
1381 public bool HasMarshalInfo {
1382 get { return marshalInfo != null; }
1386 /// Add a default value to this parameter
1388 /// <param name="c">the default value for the parameter</param>
1389 public void AddDefaultValue(Constant cVal)
1391 defaultVal = new ConstantElem(this,cVal);
1392 parMode |= (ushort) ParamAttr.HasDefault;
1396 /// Add marshalling information about this parameter
1398 public void AddMarshallInfo(NativeType marshallType)
1400 parMode |= (ushort) ParamAttr.HasFieldMarshal;
1401 marshalInfo = new FieldMarshal(this,marshallType);
1404 internal Type GetParType() { return pType; }
1406 internal sealed override void BuildTables(MetaData md)
1409 nameIx = md.AddToStringsHeap(pName);
1410 if (defaultVal != null) {
1411 md.AddToTable(MDTable.Constant,defaultVal);
1412 defaultVal.BuildTables(md);
1414 if (marshalInfo != null) {
1415 md.AddToTable(MDTable.FieldMarshal,marshalInfo);
1416 marshalInfo.BuildTables(md);
1421 internal void TypeSig(MemoryStream str)
1426 internal sealed override uint Size(MetaData md)
1428 return 4 + md.StringsIndexSize();
1431 internal sealed override void Write(FileImage output)
1433 output.Write(parMode);
1434 output.Write(seqNo);
1435 output.StringsIndex(nameIx);
1438 internal sealed override uint GetCodedIx(CIx code)
1441 case (CIx.HasCustomAttr) : return 4;
1442 case (CIx.HasConst) : return 1;
1443 case (CIx.HasFieldMarshal) : return 1;
1450 /**************************************************************************/
1451 public abstract class Signature : MetaDataElement {
1453 protected uint sigIx;
1455 internal Signature()
1457 tabIx = MDTable.StandAloneSig;
1460 internal sealed override uint Size(MetaData md)
1462 return md.BlobIndexSize();
1465 internal sealed override void Write(FileImage output)
1467 output.BlobIndex(sigIx);
1470 internal sealed override uint GetCodedIx(CIx code) { return (uint)tabIx; }
1474 /**************************************************************************/
1475 public class TypeSpec : MetaDataElement {
1478 internal TypeSpec(Type aType, MetaData md)
1480 MemoryStream sig = new MemoryStream();
1482 sigIx = md.AddToBlobHeap(sig.ToArray());
1483 tabIx = MDTable.TypeSpec;
1486 internal sealed override uint GetCodedIx(CIx code)
1489 case (CIx.TypeDefOrRef) : return 2;
1490 case (CIx.HasCustomAttr) : return 13;
1491 case (CIx.MemberRefParent) : return 4;
1496 internal override uint Size(MetaData md)
1498 return md.BlobIndexSize();
1501 internal sealed override void Write(FileImage output)
1503 //Console.WriteLine("Writing the blob index for a TypeSpec");
1504 output.BlobIndex(sigIx);
1509 /**************************************************************************/
1511 /// Base class for all IL types
1513 public abstract class Type : MetaDataElement {
1514 protected byte typeIndex;
1515 protected TypeSpec typeSpec;
1517 internal Type(byte tyIx) { typeIndex = tyIx; }
1519 internal byte GetTypeIndex() { return typeIndex; }
1520 internal void SetTypeIndex (byte b) { typeIndex = b; }
1522 internal virtual MetaDataElement GetTypeSpec(MetaData md)
1524 if (typeSpec == null) {
1525 typeSpec = new TypeSpec(this,md);
1526 md.AddToTable(MDTable.TypeSpec,typeSpec);
1531 internal virtual void TypeSig(MemoryStream str)
1533 throw(new TypeSignatureException(this.GetType().AssemblyQualifiedName +
1534 " doesn't have a type signature!!"));
1538 public class ClassRefInst : Type {
1541 private bool is_value;
1543 public ClassRefInst (Type type, bool is_value) : base (PrimitiveType.Class.GetTypeIndex ())
1546 this.is_value = is_value;
1548 typeIndex = PrimitiveType.ValueType.GetTypeIndex ();
1549 tabIx = MDTable.TypeSpec;
1552 internal sealed override void TypeSig(MemoryStream str)
1558 /**************************************************************************/
1560 /// The base descriptor for a class
1562 public abstract class Class : Type {
1564 protected int row = 0;
1565 public string name, nameSpace;
1566 protected uint nameIx, nameSpaceIx;
1567 protected MetaData _metaData;
1568 internal Class(string nameSpaceName, string className, MetaData md)
1569 : base(PrimitiveType.Class.GetTypeIndex ())
1571 nameSpace = nameSpaceName;
1573 nameIx = md.AddToStringsHeap(name);
1574 nameSpaceIx = md.AddToStringsHeap(nameSpace);
1578 internal Class(uint nsIx, uint nIx) : base(PrimitiveType.Class.GetTypeIndex ())
1584 internal Class (byte typeIndex) : base (typeIndex)
1586 nameSpace = "Should not be used";
1587 name = "Should not be used";
1590 internal virtual uint TypeDefOrRefToken() { return 0; }
1592 internal virtual void MakeValueClass(ValueClass vClass)
1594 typeIndex = PrimitiveType.ValueType.GetTypeIndex ();
1597 internal virtual string TypeName()
1599 return (nameSpace + "." + name);
1602 internal override MetaDataElement GetTypeSpec(MetaData md)
1608 /**************************************************************************/
1609 // This Class produces entries in the TypeDef table of the MetaData
1610 // in the PE meta data.
1612 // NOTE: Entry 0 in TypeDef table is always the pseudo class <module>
1613 // which is the parent for functions and variables declared a module level
1616 /// The descriptor for a class defined in the IL (.class) in the current assembly/module
1619 public class ClassDef : Class {
1622 ArrayList fields = new ArrayList();
1623 ArrayList methods = new ArrayList();
1625 ArrayList properties;
1626 bool typeIndexChecked = true;
1627 uint fieldIx = 0, methodIx = 0;
1630 ClassDef parentClass;
1633 internal ClassDef(TypeAttr attrSet, string nsName, string name,
1634 MetaData md) : base(nsName, name, md)
1637 if (! ((nsName == "" && name == "<Module>") || (nsName == "System" && name == "Object")) ) {
1638 superType = metaData.mscorlib.GetSpecialSystemClass(PrimitiveType.Object);
1640 flags = (uint)attrSet;
1641 tabIx = MDTable.TypeDef;
1644 internal void SetSuper(Class sClass)
1647 if (! (sClass is GenericTypeInst))
1648 typeIndexChecked = false;
1651 internal override void MakeValueClass(ValueClass vClass)
1653 if (vClass == ValueClass.Enum)
1654 superType = metaData.mscorlib.EnumType();
1656 superType = metaData.mscorlib.ValueType();
1658 typeIndex = PrimitiveType.ValueType.GetTypeIndex ();
1661 public void SpecialNoSuper()
1667 /// Add an attribute to this class
1669 /// <param name="ta">the attribute to be added</param>
1670 public void AddAttribute(TypeAttr ta)
1676 /// Add an interface that is implemented by this class
1678 /// <param name="iFace">the interface that is implemented</param>
1679 public void AddImplementedInterface(Class iFace)
1681 metaData.AddToTable(MDTable.InterfaceImpl,new InterfaceImpl(this,iFace));
1685 /// Add a named generic type parameter
1687 public GenericParameter AddGenericParameter (short index, string name)
1689 return AddGenericParameter (index, name, 0);
1693 /// Add a named generic type parameter with attributes
1695 public GenericParameter AddGenericParameter (short index, string name, GenericParamAttributes attr)
1697 GenericParameter gp = new GenericParameter (this, metaData, index, name, attr);
1698 metaData.AddToTable (MDTable.GenericParam, gp);
1703 /// Add a field to this class
1705 /// <param name="name">field name</param>
1706 /// <param name="fType">field type</param>
1707 /// <returns>a descriptor for this new field</returns>
1708 public FieldDef AddField(string name, Type fType)
1710 FieldDef field = new FieldDef(name,fType);
1716 /// Add a field to this class
1718 /// <param name="fAtts">attributes for this field</param>
1719 /// <param name="name">field name</param>
1720 /// <param name="fType">field type</param>
1721 /// <returns>a descriptor for this new field</returns>
1722 public FieldDef AddField(FieldAttr fAtts, string name, Type fType)
1724 FieldDef field = new FieldDef(fAtts,name,fType);
1729 public void SetFieldOrder (ArrayList fields)
1731 this.fields = fields;
1735 /// Add a method to this class
1737 /// <param name="name">method name</param>
1738 /// <param name="retType">return type</param>
1739 /// <param name="pars">parameters</param>
1740 /// <returns>a descriptor for this new method</returns>
1741 public MethodDef AddMethod(string name, Type retType, Param[] pars)
1743 return AddMethod (name, new Param (ParamAttr.Default, "", retType), pars);
1746 public MethodDef AddMethod (string name, Param ret_param, Param [] pars)
1748 // Console.WriteLine("Adding method " + name + " to class " + this.name);
1749 MethodDef meth = new MethodDef(metaData,name, ret_param, pars);
1755 /// Add a method to this class
1757 /// <param name="mAtts">attributes for this method</param>
1758 /// <param name="iAtts">implementation attributes for this method</param>
1759 /// <param name="name">method name</param>
1760 /// <param name="retType">return type</param>
1761 /// <param name="pars">parameters</param>
1762 /// <returns>a descriptor for this new method</returns>
1763 public MethodDef AddMethod(MethAttr mAtts, ImplAttr iAtts, string name,
1764 Param ret_param, Param [] pars) {
1765 // Console.WriteLine("Adding method " + name + " to class " + this.name);
1766 MethodDef meth = new MethodDef (metaData, mAtts, iAtts, name, ret_param, pars);
1772 /// Add an event to this class
1774 /// <param name="name">event name</param>
1775 /// <param name="eType">event type</param>
1776 /// <returns>a descriptor for this new event</returns>
1777 public Event AddEvent(string name, Type eType)
1779 Event e = new Event(name,eType,this);
1780 if (events == null) events = new ArrayList();
1786 /// Add a property to this class
1788 /// <param name="name">property name</param>
1789 /// <param name="propType">property type</param>
1790 /// <returns>a descriptor for this new property</returns>
1791 public Property AddProperty(string name, Type retType, Type[] pars)
1793 Property p = new Property(name, retType, pars, this);
1794 if (properties == null) properties = new ArrayList();
1800 /// Add a nested class to this class
1802 /// <param name="attrSet">attributes for this nested class</param>
1803 /// <param name="nsName">nested name space name</param>
1804 /// <param name="name">nested class name</param>
1805 /// <returns>a descriptor for this new nested class</returns>
1806 public ClassDef AddNestedClass(TypeAttr attrSet, string nsName,
1808 ClassDef nClass = new ClassDef(attrSet,"",name,metaData);
1809 metaData.AddToTable(MDTable.TypeDef,nClass);
1810 metaData.AddToTable(MDTable.NestedClass,new MapElem(nClass,Row,MDTable.TypeDef));
1811 nClass.parentClass = this;
1815 public static bool IsValueType (Class type)
1817 return IsValueType (type.nameSpace, type.name);
1820 public static bool IsEnum (Class type)
1822 return IsEnum (type.nameSpace, type.name);
1825 public static bool IsValueType (string nsName, string name)
1827 return (nsName == "System" && name == "ValueType");
1830 public static bool IsEnum (string nsName, string name)
1832 return (nsName == "System" && name == "Enum");
1836 /// Add a nested class to this class
1838 /// <param name="attrSet">attributes for this nested class</param>
1839 /// <param name="nsName">nested name space name</param>
1840 /// <param name="name">nested class name</param>
1841 /// <param name="sType">super type of this nested class</param>
1842 /// <returns>a descriptor for this new nested class</returns>
1843 public ClassDef AddNestedClass(TypeAttr attrSet, string nsName,
1844 string name, Class sType) {
1845 ClassDef nClass = AddNestedClass (attrSet, nsName, name);
1846 nClass.SetSuper(sType);
1847 if (ClassDef.IsValueType (sType))
1848 nClass.MakeValueClass (ValueClass.ValueType);
1850 if (ClassDef.IsEnum (sType))
1851 nClass.MakeValueClass (ValueClass.Enum);
1853 if (ClassDef.IsValueType (sType) || ClassDef.IsEnum (sType))
1854 nClass.SetTypeIndex (PrimitiveType.ValueType.GetTypeIndex ());
1856 nClass.typeIndexChecked = true;
1861 /// Add layout information for this class. This class must have the
1862 /// sequential or explicit attribute.
1864 /// <param name="packSize">packing size (.pack)</param>
1865 /// <param name="classSize">class size (.size)</param>
1866 public void AddLayoutInfo (int packSize, int classSize)
1868 layout = new ClassLayout(packSize,classSize,this);
1872 /// Use a method as the implementation for another method (.override)
1874 /// <param name="decl">the method to be overridden</param>
1875 /// <param name="body">the implementation to be used</param>
1876 public void AddMethodOverride(Method decl, Method body)
1878 metaData.AddToTable(MDTable.MethodImpl,new MethodImpl(this,decl,body));
1882 /// Add security to this class NOT YET IMPLEMENTED
1884 /// <param name="permissionSet"></param>
1885 public void AddSecurity(byte[] permissionSet)
1887 throw(new NotYetImplementedException("Class security "));
1888 //flags |= HasSecurity;
1889 // securityActions = permissionSet;
1892 //public void AddLineInfo(int row, int col) { }
1894 internal void CheckTypeIndex()
1896 if (typeIndexChecked) return;
1897 if (superType is ClassDef)
1898 ((ClassDef)superType).CheckTypeIndex();
1899 typeIndex = superType.GetTypeIndex();
1900 typeIndexChecked = true;
1903 internal sealed override void BuildTables(MetaData md)
1906 if ((flags & (uint)TypeAttr.Interface) != 0) { superType = null; }
1907 // Console.WriteLine("Building tables for " + name);
1908 if (layout != null) md.AddToTable(MDTable.ClassLayout,layout);
1909 // Console.WriteLine("adding methods " + methods.Count);
1910 methodIx = md.TableIndex(MDTable.Method);
1911 for (int i=0; i < methods.Count; i++) {
1912 md.AddToTable(MDTable.Method,(MetaDataElement)methods[i]);
1913 ((MethodDef)methods[i]).BuildTables(md);
1915 // Console.WriteLine("adding fields");
1916 fieldIx = md.TableIndex(MDTable.Field);
1917 for (int i=0; i < fields.Count; i++) {
1918 md.AddToTable(MDTable.Field,(MetaDataElement)fields[i]);
1919 ((FieldDef)fields[i]).BuildTables(md);
1921 // Console.WriteLine("adding events and properties");
1922 if (events != null) {
1923 for (int i=0; i < events.Count; i++) {
1924 md.AddToTable(MDTable.Event,(Event)events[i]);
1925 ((Event)events[i]).BuildTables(md);
1927 md.AddToTable(MDTable.EventMap,
1928 new MapElem(this,((Event)events[0]).Row,MDTable.Event));
1930 if (properties != null) {
1931 for (int i=0; i < properties.Count; i++) {
1932 md.AddToTable(MDTable.Property,(Property)properties[i]);
1933 ((Property)properties[i]).BuildTables(md);
1935 md.AddToTable(MDTable.PropertyMap,new MapElem(this,
1936 ((Property)properties[0]).Row,MDTable.Property));
1938 // Console.WriteLine("End of building tables");
1942 internal sealed override uint Size(MetaData md)
1944 return 4 + 2 * md.StringsIndexSize() +
1945 md.CodedIndexSize(CIx.TypeDefOrRef) +
1946 md.TableIndexSize(MDTable.Field) +
1947 md.TableIndexSize(MDTable.Method);
1950 internal sealed override void Write(FileImage output)
1952 output.Write(flags);
1953 output.StringsIndex(nameIx);
1954 output.StringsIndex(nameSpaceIx);
1955 //if (superType != null)
1956 // Console.WriteLine("getting coded index for superType of " + name + " = " + superType.GetCodedIx(CIx.TypeDefOrRef));
1957 output.WriteCodedIndex(CIx.TypeDefOrRef,superType);
1958 output.WriteIndex(MDTable.Field,fieldIx);
1959 output.WriteIndex(MDTable.Method,methodIx);
1962 internal sealed override uint TypeDefOrRefToken()
1969 internal sealed override void TypeSig(MemoryStream sig)
1971 if (!typeIndexChecked) CheckTypeIndex();
1972 sig.WriteByte(GetTypeIndex());
1973 MetaData.CompressNum(TypeDefOrRefToken(),sig);
1976 internal sealed override uint GetCodedIx(CIx code)
1979 case (CIx.TypeDefOrRef) : return 0;
1980 case (CIx.HasCustomAttr) : return 3;
1981 case (CIx.HasDeclSecurity) : return 0;
1982 case (CIx.TypeOrMethodDef) : return 0;
1989 /**************************************************************************/
1991 /// Descriptor for a class/interface declared in another module of THIS
1992 /// assembly, or in another assembly.
1994 public class ClassRef : Class, IExternRef, IResolutionScope {
1996 protected IResolutionScope parent;
1997 protected MetaData metaData;
1999 internal ClassRef(string nsName, string name, MetaData md) : base(nsName, name, md)
2002 tabIx = MDTable.TypeRef;
2006 /// Add a method to this class
2008 /// <param name="name">method name</param>
2009 /// <param name="retType">return type</param>
2010 /// <param name="pars">parameter types</param>
2011 /// <returns>a descriptor for this method</returns>
2012 public MethodRef AddMethod(string name, Type retType, Type[] pars)
2014 return AddMethod (name, retType, pars, 0);
2018 /// Add a method to this class
2020 /// <param name="name">method name</param>
2021 /// <param name="retType">return type</param>
2022 /// <param name="pars">parameter types</param>
2023 /// <param name="gen_param_count">num of generic parameters</param>
2024 /// <returns>a descriptor for this method</returns>
2025 public MethodRef AddMethod (string name, Type retType, Type[] pars, int gen_param_count)
2027 MethodRef meth = new MethodRef (this, name, retType, pars, false, null, gen_param_count);
2028 metaData.AddToTable(MDTable.MemberRef,meth);
2033 /// Add a method to this class
2035 /// <param name="name">method name</param>
2036 /// <param name="retType">return type</param>
2037 /// <param name="pars">parameter types</param>
2038 /// <returns>a descriptor for this method</returns>
2039 public MethodRef AddVarArgMethod(string name, Type retType,
2040 Type[] pars, Type[] optPars)
2042 MethodRef meth = new MethodRef(this,name,retType,pars,true,optPars, 0);
2043 metaData.AddToTable(MDTable.MemberRef,meth);
2048 /// Add a field to this class
2050 /// <param name="name">field name</param>
2051 /// <param name="fType">field type</param>
2052 /// <returns>a descriptor for this field</returns>
2053 public FieldRef AddField(string name, Type fType)
2055 FieldRef field = new FieldRef(this,name,fType);
2056 metaData.AddToTable(MDTable.MemberRef,field);
2060 public ClassRef AddClass (string nsName, string name)
2062 ClassRef aClass = new ClassRef(nsName,name,metaData);
2063 metaData.AddToTable(MDTable.TypeRef,aClass);
2064 aClass.SetParent(this);
2068 public ClassRef AddValueClass (string nsName, string name)
2070 ClassRef aClass = AddClass (nsName, name);
2071 aClass.MakeValueClass (ValueClass.ValueType);
2075 internal void SetParent(IResolutionScope par)
2080 internal override string TypeName()
2082 if ((parent != null) && (parent is AssemblyRef))
2083 return (nameSpace + "." + name + ", " + ((AssemblyRef)parent).TypeName());
2085 return (nameSpace + name);
2088 internal sealed override uint Size(MetaData md)
2090 return md.CodedIndexSize(CIx.ResolutionScope) + 2 *
2091 md.StringsIndexSize();
2094 internal sealed override void Write(FileImage output)
2096 output.WriteCodedIndex(CIx.ResolutionScope,(MetaDataElement) parent);
2097 output.StringsIndex(nameIx);
2098 output.StringsIndex(nameSpaceIx);
2101 internal override sealed uint TypeDefOrRefToken()
2104 cIx = (cIx << 2) | 0x1;
2108 internal override void TypeSig(MemoryStream sig)
2110 sig.WriteByte(GetTypeIndex());
2111 MetaData.CompressNum(TypeDefOrRefToken(),sig);
2114 internal sealed override uint GetCodedIx(CIx code)
2117 case (CIx.TypeDefOrRef) : return 1;
2118 case (CIx.HasCustomAttr) : return 2;
2119 case (CIx.MemberRefParent) : return 1;
2120 case (CIx.ResolutionScope) : return 3;
2127 /**************************************************************************/
2128 public class ExternClassRef : ClassRef {
2130 ExternClass externClass;
2132 internal ExternClassRef(TypeAttr attrs, string nsName, string name,
2133 MetaDataElement declRef, MetaData md) : base(nsName,name,md)
2135 externClass = new ExternClass(attrs,nameSpaceIx,nameIx,declRef);
2136 metaData.AddToTable(MDTable.ExportedType,externClass);
2139 internal ExternClassRef(string name, MetaData md) : base(null,name,md)
2143 public ClassRef AddNestedClass(TypeAttr attrs, string name)
2145 ExternClassRef nestedClass = new ExternClassRef(name,metaData);
2146 externClass = new ExternClass(attrs,0,nameIx,this.externClass);
2147 metaData.AddToTable(MDTable.ExportedType,externClass);
2153 /**************************************************************************/
2155 /// Descriptor for a class defined in another module of THIS assembly
2156 /// and exported (.class extern)
2159 internal class ExternClass : Class {
2161 MetaDataElement parent;
2164 internal ExternClass(TypeAttr attr, uint nsIx, uint nIx,
2165 MetaDataElement paren) : base(nsIx,nIx)
2169 tabIx = MDTable.ExportedType;
2172 internal sealed override uint Size(MetaData md)
2174 return 8 + 2* md.StringsIndexSize() + md.CodedIndexSize(CIx.Implementation);
2177 internal sealed override void Write(FileImage output)
2179 output.Write(flags);
2181 output.StringsIndex(nameIx);
2182 output.StringsIndex(nameSpaceIx);
2183 output.WriteCodedIndex(CIx.Implementation,parent);
2186 internal sealed override uint GetCodedIx(CIx code)
2189 case (CIx.HasCustomAttr) : return 17;
2190 case (CIx.Implementation) : return 2;
2197 public class GenParam : Class {
2200 private string param_name;
2201 private uint sigIx = 0;
2203 public GenParam (int index, string name, GenParamType ptype) : base ((byte) ptype)
2206 this.param_name = name;
2207 tabIx = MDTable.TypeSpec;
2211 get { return index; }
2212 set { index = value; }
2215 public string Name {
2216 get { return param_name; }
2217 set { param_name = value; }
2220 public GenParamType Type {
2221 get { return (GenParamType) GetTypeIndex (); }
2224 internal sealed override void BuildTables (MetaData md)
2228 MemoryStream str = new MemoryStream ();
2230 sigIx = md.AddToBlobHeap (str.ToArray ());
2235 internal sealed override void TypeSig(MemoryStream str)
2238 throw new PEFileException (String.Format ("Unresolved {0} - {1}", (GenParamType) GetTypeIndex (), param_name));
2239 str.WriteByte(typeIndex);
2240 MetaData.CompressNum ((uint) index, str);
2243 internal override uint Size(MetaData md)
2245 return md.BlobIndexSize();
2248 internal sealed override void Write (FileImage output)
2250 output.BlobIndex (sigIx);
2253 internal sealed override uint GetCodedIx(CIx code)
2256 case (CIx.TypeDefOrRef) : return 2;
2257 case (CIx.HasCustomAttr) : return 13;
2258 case (CIx.MemberRefParent) : return 4;
2264 public class GenericTypeInst : Class {
2266 private Type gen_type;
2267 private Type[] gen_param;
2268 bool inTable = false;
2271 public GenericTypeInst (Type gen_type, Type[] gen_param)
2272 : base ((byte) PrimitiveType.GenericInst.GetTypeIndex ())
2274 this.gen_type = gen_type;
2275 this.gen_param = gen_param;
2276 tabIx = MDTable.TypeSpec;
2279 internal override MetaDataElement GetTypeSpec (MetaData md)
2282 md.AddToTable (MDTable.TypeSpec, this);
2289 internal sealed override void TypeSig(MemoryStream str)
2291 str.WriteByte(typeIndex);
2292 gen_type.TypeSig (str);
2293 MetaData.CompressNum ((uint) gen_param.Length, str);
2294 foreach (Type param in gen_param)
2295 param.TypeSig (str);
2298 internal sealed override void BuildTables (MetaData md)
2302 MemoryStream str = new MemoryStream ();
2304 sigIx = md.AddToBlobHeap (str.ToArray ());
2309 internal sealed override uint Size (MetaData md)
2311 return md.BlobIndexSize ();
2314 internal sealed override void Write (FileImage output)
2316 output.BlobIndex (sigIx);
2319 internal sealed override uint GetCodedIx (CIx code)
2322 case (CIx.TypeDefOrRef): return 2;
2323 case (CIx.MemberRefParent): return 4;
2324 case (CIx.HasCustomAttr): return 13;
2330 public class GenericMethodSig {
2332 private Type[] gen_param;
2334 private uint sigIx = 0;
2336 public GenericMethodSig (Type[] gen_param)
2338 this.gen_param = gen_param;
2342 internal void TypeSig (MemoryStream str)
2344 str.WriteByte (0x0A); /* GENERIC_INST */
2345 MetaData.CompressNum ((uint) gen_param.Length, str);
2346 foreach (Type param in gen_param)
2347 param.TypeSig (str);
2350 internal uint GetSigIx (MetaData md)
2355 MemoryStream sig = new MemoryStream();
2357 sigIx = md.AddToBlobHeap (sig.ToArray());
2363 public class Sentinel : Type {
2365 public Sentinel () : base (0x41) { }
2367 internal sealed override void TypeSig(MemoryStream str)
2369 str.WriteByte(typeIndex);
2373 /**************************************************************************/
2375 /// Descriptor for a FunctionPointer type
2378 public class MethPtrType : Type {
2390 /// Create a new function pointer type
2392 /// <param name="meth">the function to be referenced</param>
2393 public MethPtrType (CallConv callconv, Type retType, Type[] pars,
2394 bool varArgMeth, Type[] optPars) : base(0x1B)
2396 this.retType = retType;
2397 callConv = callconv;
2399 this.varArgMeth = varArgMeth;
2400 if (parList != null) numPars = (uint)parList.Length;
2402 optParList = optPars;
2403 if (optParList != null) numOptPars = (uint)optParList.Length;
2404 callConv |= CallConv.Vararg;
2406 tabIx = MDTable.TypeSpec;
2409 internal sealed override void TypeSig(MemoryStream sig)
2411 sig.WriteByte(typeIndex);
2412 // Bootlegged from method ref
2413 sig.WriteByte((byte)callConv);
2414 MetaData.CompressNum (numPars + numOptPars, sig);
2415 retType.TypeSig (sig);
2416 for (int i=0; i < numPars; i++) {
2417 parList[i].TypeSig (sig);
2420 sig.WriteByte (0x41); // Write the sentinel
2421 for (int i=0; i < numOptPars; i++) {
2422 optParList[i].TypeSig (sig);
2427 internal sealed override void BuildTables(MetaData md)
2430 MemoryStream sig = new MemoryStream();
2432 sigIx = md.AddToBlobHeap(sig.ToArray());
2436 internal sealed override uint Size(MetaData md)
2438 return md.BlobIndexSize();
2441 internal sealed override void Write(FileImage output)
2443 output.BlobIndex(sigIx);
2446 internal sealed override uint GetCodedIx(CIx code) { return 0x1B; }
2451 /* Classes for Arrays */
2454 /// The IL Array type
2456 public abstract class Array : Type {
2458 protected Type elemType;
2459 protected MetaData metaData;
2460 protected string cnameSpace, cname;
2462 internal Array(Type eType, byte TypeId) : base(TypeId)
2465 tabIx = MDTable.TypeSpec;
2470 /// Single dimensional array with zero lower bound
2472 public class ZeroBasedArray : Array {
2475 /// Create a new array - elementType[]
2477 /// <param name="elementType">the type of the array elements</param>
2478 public ZeroBasedArray(Type elementType) : base (elementType, PrimitiveType.SZArray.GetTypeIndex ()) { }
2480 internal sealed override void TypeSig(MemoryStream str)
2482 str.WriteByte(typeIndex);
2483 elemType.TypeSig(str);
2489 /// Multi dimensional array with explicit bounds
2491 public class BoundArray : Array {
2497 /// Create a new multi dimensional array type
2498 /// eg. elemType[1..5,3..10,5,,] would be
2499 /// new BoundArray(elemType,5,[1,3,0],[5,10,4])
2501 /// <param name="elementType">the type of the elements</param>
2502 /// <param name="dimensions">the number of dimensions</param>
2503 /// <param name="loBounds">lower bounds of dimensions</param>
2504 /// <param name="sizes">sizes for the dimensions</param>
2505 public BoundArray(Type elementType, uint dimensions, int[] loBounds,
2506 int[] sizes) : base (elementType,0x14)
2508 numDims = dimensions;
2509 lowerBounds = loBounds;
2514 /// Create a new multi dimensional array type
2515 /// eg. elemType[5,10,20] would be new BoundArray(elemType,3,[5,10,20])
2517 /// <param name="elementType">the type of the elements</param>
2518 /// <param name="dimensions">the number of dimensions</param>
2519 /// <param name="size">the sizes of the dimensions</param>
2520 public BoundArray(Type elementType, uint dimensions, int[] size)
2521 : base (elementType,0x14)
2523 numDims = dimensions;
2528 /// Create a new multi dimensional array type
2529 /// eg. elemType[,,] would be new BoundArray(elemType,3)
2531 /// <param name="elementType">the type of the elements</param>
2532 /// <param name="dimensions">the number of dimensions</param>
2533 public BoundArray(Type elementType, uint dimensions)
2534 : base (elementType,0x14)
2536 numDims = dimensions;
2539 internal sealed override void TypeSig(MemoryStream str)
2541 str.WriteByte(typeIndex);
2542 elemType.TypeSig(str);
2543 MetaData.CompressNum(numDims,str);
2544 if ((sizes != null) && (sizes.Length > 0)) {
2546 MetaData.CompressNum((uint)sizes.Length,str);
2547 for (int i=0; i < sizes.Length; i++) {
2548 MetaData.CompressNum((uint)sizes[i],str);
2550 } else str.WriteByte(0);
2551 if ((lowerBounds != null) && (lowerBounds.Length > 0)) {
2552 MetaData.CompressNum((uint)lowerBounds.Length,str);
2553 for (int i=0; i < lowerBounds.Length; i++) {
2554 CompressSignedNum (lowerBounds[i],str);
2556 } else str.WriteByte(0);
2558 private void CompressSignedNum (int val, MemoryStream str)
2560 uint uval = (uint) val;
2567 /* Map the signed number to an unsigned number in two ways.
2569 fval: left-rotated 2's complement representation
2570 sval: map the signed number to unsigned as follows: 0 -> 0, -1 -> 1, 1 -> 2, -2 -> 3, 2 -> 4, ....
2571 the mapping is: x -> 2*|x| - signbit(x)
2573 uint fval = (uval << 1) | sign;
2574 int sval = (val << 1) - sign;
2576 /* An overly clever transformation:
2578 a. sval is used to determine the number of bytes in the compressed representation.
2579 b. fval is truncated to the appropriate number of bits and output using the
2580 normal unsigned-int compressor.
2582 However, or certain values, the truncated fval doesn't carry enough information to round trip.
2584 (fval & 0x3FFF) <= 0x7F => compressor emits 1 byte, not 2 => there is aliasing of values
2586 So, we use full 4 bytes to encode such values.
2588 LAMESPEC: The Microsoft implementation doesn't appear to handle this subtle case.
2589 e.g., it ends up encoding -8192 as the byte 0x01, which decodes to -64
2592 MetaData.CompressNum (fval & 0x7F, str);
2593 else if (sval <= 0x3FFF && (fval & 0x3FFF) > 0x7F)
2594 MetaData.CompressNum (fval & 0x3FFF, str);
2595 else if (sval <= 0x1FFFFFFF && (fval & 0x1FFFFFFF) > 0x3FFF)
2596 MetaData.CompressNum (fval & 0x1FFFFFFF, str);
2598 /* FIXME: number cannot be represented. Report a warning. */
2599 // throw new Exception ("cannot represent signed value" + -val);
2600 MetaData.CompressNum (fval, str);
2607 /* Empty interface for grouping TypeRef's possible ResolutionScope
2608 namely : Module, ModuleRef, AssemblyRef and TypeRef */
2609 public interface IResolutionScope {
2612 /**************************************************************************/
2614 /// Base class for scopes (extended by Module, ModuleRef, Assembly, AssemblyRef)
2616 public abstract class ResolutionScope : MetaDataElement, IResolutionScope {
2618 protected uint nameIx = 0;
2619 protected MetaData metaData;
2620 protected string name;
2622 internal ResolutionScope(string name, MetaData md)
2626 nameIx = md.AddToStringsHeap(name);
2629 internal string GetName() { return name; }
2633 /**************************************************************************/
2635 /// Descriptor for THIS assembly (.assembly)
2637 public class Assembly : ResolutionScope {
2639 ushort majorVer, minorVer, buildNo, revisionNo;
2642 uint keyIx = 0, cultIx = 0;
2643 bool hasPublicKey = false;
2645 internal Assembly(string name, MetaData md) : base(name,md)
2647 tabIx = MDTable.Assembly;
2651 /// Add details about THIS assembly
2653 /// <param name="majVer">Major Version</param>
2654 /// <param name="minVer">Minor Version</param>
2655 /// <param name="bldNo">Build Number</param>
2656 /// <param name="revNo">Revision Number</param>
2657 /// <param name="key">Hash Key</param>
2658 /// <param name="hash">Hash Algorithm</param>
2659 /// <param name="cult">Culture</param>
2660 public void AddAssemblyInfo(int majVer, int minVer, int bldNo, int revNo,
2661 byte[] key, uint hash, string cult)
2663 majorVer = (ushort)majVer;
2664 minorVer = (ushort)minVer;
2665 buildNo = (ushort)bldNo;
2666 revisionNo = (ushort)revNo;
2668 hasPublicKey = (key != null);
2669 keyIx = metaData.AddToBlobHeap(key);
2670 cultIx = metaData.AddToStringsHeap(cult);
2674 /// Add an attribute to THIS assembly
2676 /// <param name="aa">assembly attribute</param>
2677 public void AddAssemblyAttr(AssemAttr aa)
2682 internal sealed override uint Size(MetaData md)
2684 return 16 + md.BlobIndexSize() + 2 * md.StringsIndexSize();
2687 internal sealed override void Write(FileImage output)
2689 // Console.WriteLine("Writing assembly element with nameIx of " + nameIx + " at file offset " + output.Seek(0,SeekOrigin.Current));
2690 output.Write((uint)hashAlgId);
2691 output.Write(majorVer);
2692 output.Write(minorVer);
2693 output.Write(buildNo);
2694 output.Write(revisionNo);
2695 output.Write(flags);
2696 output.BlobIndex(keyIx);
2697 output.StringsIndex(nameIx);
2698 output.StringsIndex(cultIx);
2701 internal sealed override uint GetCodedIx(CIx code)
2704 case (CIx.HasCustomAttr) : return 14;
2705 case (CIx.HasDeclSecurity) : return 2;
2710 internal bool HasPublicKey {
2711 get { return hasPublicKey; }
2715 /**************************************************************************/
2717 /// Descriptor for THIS module
2719 public class Module : ResolutionScope, IExternRef {
2724 internal Module(string name, MetaData md) : base(name,md)
2726 mvid = Guid.NewGuid();
2727 mvidIx = md.AddToGUIDHeap(mvid);
2728 tabIx = MDTable.Module;
2732 get { return mvid; }
2735 public ClassRef AddClass(string nsName, string name)
2737 ClassRef aClass = new ClassRef (nsName, name, metaData);
2738 metaData.AddToTable (MDTable.TypeRef, aClass);
2739 aClass.SetParent (this);
2743 public ClassRef AddValueClass(string nsName, string name)
2745 ClassRef aClass = AddClass (nsName, name);
2746 aClass.MakeValueClass (ValueClass.ValueType);
2750 internal sealed override uint Size(MetaData md)
2752 return 2 + md.StringsIndexSize() + 3 * md.GUIDIndexSize();
2755 internal sealed override void Write(FileImage output)
2757 output.Write((short)0);
2758 output.StringsIndex(nameIx);
2759 output.GUIDIndex(mvidIx);
2760 output.GUIDIndex(0);
2761 output.GUIDIndex(0);
2764 internal sealed override uint GetCodedIx(CIx code)
2767 case (CIx.HasCustomAttr) : return 7;
2768 case (CIx.ResolutionScope) : return 0;
2773 /**************************************************************************/
2775 /// Descriptor for another module in THIS assembly
2777 public class ModuleRef : ResolutionScope, IExternRef {
2779 internal ModuleRef(MetaData md, string name) : base(name,md)
2781 tabIx = MDTable.ModuleRef;
2785 /// Add a class to this external module. This is a class declared in
2786 /// another module of THIS assembly.
2788 /// <param name="nsName">name space name</param>
2789 /// <param name="name">class name</param>
2790 /// <returns>a descriptor for this class in another module</returns>
2791 public ClassRef AddClass(string nsName, string name)
2793 ClassRef aClass = new ClassRef(nsName,name,metaData);
2794 metaData.AddToTable(MDTable.TypeRef,aClass);
2795 aClass.SetParent(this);
2800 /// Make a file descriptor to correspond to this module. The file
2801 /// descriptor will have the same name as the module descriptor
2803 /// <param name="hashBytes">the hash of the file</param>
2804 /// <param name="hasMetaData">the file contains metadata</param>
2805 /// <param name="entryPoint">the program entry point is in this file</param>
2806 /// <returns>a descriptor for the file which contains this module</returns>
2807 public FileRef MakeFile(byte[] hashBytes, bool hasMetaData, bool entryPoint)
2809 FileRef file = new FileRef(nameIx,hashBytes,hasMetaData,entryPoint,metaData);
2810 metaData.AddToTable(MDTable.File,file);
2815 /// Add a value class to this module. This is a class declared in
2816 /// another module of THIS assembly.
2818 /// <param name="nsName">name space name</param>
2819 /// <param name="name">class name</param>
2820 /// <returns></returns>
2821 public ClassRef AddValueClass(string nsName, string name)
2823 ClassRef aClass = new ClassRef(nsName,name,metaData);
2824 metaData.AddToTable(MDTable.TypeRef,aClass);
2825 aClass.SetParent(this);
2826 aClass.MakeValueClass(ValueClass.ValueType);
2831 /// Add a class which is declared public in this external module of
2832 /// THIS assembly. This class will be exported from this assembly.
2833 /// The ilasm syntax for this is .extern class
2835 /// <param name="attrSet">attributes of the class to be exported</param>
2836 /// <param name="nsName">name space name</param>
2837 /// <param name="name">external class name</param>
2838 /// <param name="declFile">the file where the class is declared</param>
2839 /// <param name="isValueClass">is this class a value type?</param>
2840 /// <returns>a descriptor for this external class</returns>
2841 public ExternClassRef AddExternClass(TypeAttr attrSet, string nsName,
2842 string name, FileRef declFile,
2843 bool isValueClass) {
2844 ExternClassRef cRef = new ExternClassRef(attrSet,nsName,name,declFile,metaData);
2845 metaData.AddToTable(MDTable.TypeRef,cRef);
2846 cRef.SetParent(this);
2847 if (isValueClass) cRef.MakeValueClass(ValueClass.ValueType);
2852 /// Add a "global" method in another module
2854 /// <param name="name">method name</param>
2855 /// <param name="retType">return type</param>
2856 /// <param name="pars">method parameter types</param>
2857 /// <returns>a descriptor for this method in anther module</returns>
2858 public MethodRef AddMethod(string name, Type retType, Type[] pars)
2860 MethodRef meth = new MethodRef(this,name,retType,pars,false,null, 0);
2861 metaData.AddToTable(MDTable.MemberRef,meth);
2866 /// Add a vararg method to this class
2868 /// <param name="name">method name</param>
2869 /// <param name="retType">return type</param>
2870 /// <param name="pars">parameter types</param>
2871 /// <param name="optPars">optional param types for this vararg method</param>
2872 /// <returns>a descriptor for this method</returns>
2873 public MethodRef AddVarArgMethod(string name, Type retType,
2874 Type[] pars, Type[] optPars) {
2875 MethodRef meth = new MethodRef(this,name,retType,pars,true,optPars, 0);
2876 metaData.AddToTable(MDTable.MemberRef,meth);
2881 /// Add a field in another module
2883 /// <param name="name">field name</param>
2884 /// <param name="fType">field type</param>
2885 /// <returns>a descriptor for this field in another module</returns>
2886 public FieldRef AddField(string name, Type fType)
2888 FieldRef field = new FieldRef(this,name,fType);
2889 metaData.AddToTable(MDTable.MemberRef,field);
2893 internal sealed override uint Size(MetaData md)
2895 return md.StringsIndexSize();
2898 internal sealed override void Write(FileImage output)
2900 output.StringsIndex(nameIx);
2903 internal sealed override uint GetCodedIx(CIx code)
2906 case (CIx.HasCustomAttr) : return 12;
2907 case (CIx.MemberRefParent) : return 2;
2908 case (CIx.ResolutionScope) : return 1;
2915 #region Classes for Constants
2917 /// Descriptor for a constant value
2919 public abstract class Constant {
2920 protected uint size = 0;
2921 protected Type type;
2922 protected uint blobIndex;
2923 protected bool addedToBlobHeap = false;
2925 internal Constant() { }
2927 internal virtual uint GetBlobIndex(MetaData md) { return 0; }
2929 internal uint GetSize() { return size; }
2931 internal byte GetTypeIndex() { return type.GetTypeIndex(); }
2933 internal virtual void Write(BinaryWriter bw) { }
2937 /// Descriptor for a constant value
2939 public abstract class DataConstant : Constant {
2940 private uint dataOffset = 0;
2942 internal DataConstant() { }
2944 public uint DataOffset {
2945 get { return dataOffset; }
2946 set { dataOffset = value; }
2952 /// Boolean constant
2954 public class BoolConst : DataConstant {
2958 /// Create a new boolean constant with the value "val"
2960 /// <param name="val">value of this boolean constant</param>
2961 public BoolConst(bool val)
2965 type = PrimitiveType.Boolean;
2968 internal sealed override uint GetBlobIndex(MetaData md)
2970 if (!addedToBlobHeap) {
2971 if (val) blobIndex = md.AddToBlobHeap((sbyte)1);
2972 else blobIndex = md.AddToBlobHeap((sbyte)0);
2973 addedToBlobHeap = true;
2978 internal sealed override void Write(BinaryWriter bw)
2980 if (val) bw.Write((sbyte)1);
2981 else bw.Write((sbyte)0);
2986 public class ByteArrConst : DataConstant {
2987 internal byte[] val;
2989 public ByteArrConst(byte[] val)
2991 type = PrimitiveType.String;
2993 size = (uint)val.Length;
2997 get { return type; }
2998 set { type = value; }
3001 internal sealed override uint GetBlobIndex(MetaData md)
3003 if (!addedToBlobHeap) {
3004 blobIndex = md.AddToBlobHeap(val);
3005 addedToBlobHeap = true;
3010 internal sealed override void Write(BinaryWriter bw)
3017 public class CharConst : Constant {
3020 public CharConst(char val)
3024 type = PrimitiveType.Char;
3027 internal sealed override uint GetBlobIndex(MetaData md)
3029 if (!addedToBlobHeap) {
3030 blobIndex = md.AddToBlobHeap(val);
3031 addedToBlobHeap = true;
3036 internal sealed override void Write(BinaryWriter bw)
3043 public class FloatConst : DataConstant {
3046 public FloatConst(float val)
3050 type = PrimitiveType.Float32;
3053 internal sealed override uint GetBlobIndex(MetaData md)
3055 if (!addedToBlobHeap) {
3056 blobIndex = md.AddToBlobHeap(val);
3057 addedToBlobHeap = true;
3062 internal sealed override void Write(BinaryWriter bw)
3069 public class DoubleConst : DataConstant {
3072 public DoubleConst(double val)
3076 type = PrimitiveType.Float64;
3079 internal sealed override uint GetBlobIndex(MetaData md)
3081 if (!addedToBlobHeap) {
3082 blobIndex = md.AddToBlobHeap(val);
3083 addedToBlobHeap = true;
3088 internal sealed override void Write(BinaryWriter bw)
3095 public class IntConst : DataConstant {
3098 public IntConst(sbyte val)
3102 type = PrimitiveType.Int8;
3105 public IntConst(short val)
3109 type = PrimitiveType.Int16;
3112 public IntConst(int val)
3116 type = PrimitiveType.Int32;
3119 public IntConst(long val)
3123 type = PrimitiveType.Int64;
3126 internal sealed override uint GetBlobIndex(MetaData md)
3128 if (!addedToBlobHeap) {
3130 case (1) : blobIndex = md.AddToBlobHeap((sbyte)val); break;
3131 case (2) : blobIndex = md.AddToBlobHeap((short)val); break;
3132 case (4) : blobIndex = md.AddToBlobHeap((int)val); break;
3133 default : blobIndex = md.AddToBlobHeap(val); break;
3135 addedToBlobHeap = true;
3140 internal sealed override void Write(BinaryWriter bw)
3143 case (1) : bw.Write((sbyte)val); break;
3144 case (2) : bw.Write((short)val); break;
3145 case (4) : bw.Write((int)val); break;
3146 default : bw.Write(val); break;
3152 public class UIntConst : Constant {
3155 public UIntConst(byte val)
3159 type = PrimitiveType.UInt8;
3161 public UIntConst(ushort val)
3165 type = PrimitiveType.UInt16;
3167 public UIntConst(uint val)
3171 type = PrimitiveType.UInt32;
3173 public UIntConst(ulong val)
3177 type = PrimitiveType.UInt64;
3180 internal sealed override uint GetBlobIndex(MetaData md)
3182 if (!addedToBlobHeap) {
3184 case (1) : blobIndex = md.AddToBlobHeap((byte)val); break;
3185 case (2) : blobIndex = md.AddToBlobHeap((ushort)val); break;
3186 case (4) : blobIndex = md.AddToBlobHeap((uint)val); break;
3187 default : blobIndex = md.AddToBlobHeap(val); break;
3189 addedToBlobHeap = true;
3194 internal sealed override void Write(BinaryWriter bw)
3197 case (1) : bw.Write((byte)val); break;
3198 case (2) : bw.Write((ushort)val); break;
3199 case (4) : bw.Write((uint)val); break;
3200 default : bw.Write(val); break;
3206 public class StringConst : DataConstant {
3207 internal string val;
3209 public StringConst(string val)
3212 size = (uint)val.Length; // need to add null ??
3213 type = PrimitiveType.String;
3216 internal sealed override uint GetBlobIndex(MetaData md)
3218 if (!addedToBlobHeap) {
3219 byte [] b = Encoding.Unicode.GetBytes (val);
3220 blobIndex = md.AddToBlobHeap(b);
3221 addedToBlobHeap = true;
3226 internal sealed override void Write(BinaryWriter bw)
3233 public class NullConst : Constant {
3238 type = PrimitiveType.Class;
3241 internal sealed override uint GetBlobIndex(MetaData md)
3243 if (!addedToBlobHeap) {
3244 blobIndex = md.AddToBlobHeap((int)0);
3245 addedToBlobHeap = true;
3250 internal sealed override void Write(BinaryWriter bw)
3257 public class AddressConstant : DataConstant {
3260 public AddressConstant(DataConstant dConst)
3264 type = PrimitiveType.TypedRef;
3267 internal sealed override void Write(BinaryWriter bw)
3269 ((FileImage)bw).WriteDataRVA(data.DataOffset);
3274 public class RepeatedConstant : DataConstant {
3278 public RepeatedConstant(DataConstant dConst, int repeatCount)
3281 repCount = (uint)repeatCount;
3282 int[] sizes = new int[1];
3283 sizes[0] = repeatCount;
3284 type = new BoundArray(type,1,sizes);
3285 size = data.GetSize() * repCount;
3288 internal sealed override void Write(BinaryWriter bw)
3290 for (int i=0; i < repCount; i++) {
3297 public class ArrayConstant : DataConstant {
3298 DataConstant[] dataVals;
3300 public ArrayConstant(DataConstant[] dVals)
3303 for (int i=0; i < dataVals.Length; i++) {
3304 size += dataVals[i].GetSize();
3308 public int? ExplicitSize { get; set; }
3310 internal sealed override void Write(BinaryWriter bw)
3312 for (int i=0; i < dataVals.Length; i++) {
3313 dataVals[i].Write(bw);
3319 public class ClassType : Constant {
3323 public ClassType(string className)
3326 type = PrimitiveType.ClassType;
3329 public ClassType(Class classDesc)
3332 type = PrimitiveType.ClassType;
3335 internal override void Write(BinaryWriter bw)
3337 if (name == null) name = desc.TypeName();
3345 /**************************************************************************/
3347 /// Descriptor for a custom modifier of a type (modopt or modreq)
3350 public class CustomModifiedType : Type {
3354 PrimitiveTypeRef cmodPrimType;
3357 /// Create a new custom modifier for a type
3359 /// <param name="type">the type to be modified</param>
3360 /// <param name="cmod">the modifier</param>
3361 /// <param name="cmodType">the type reference to be associated with the type</param>
3362 public CustomModifiedType(Type type, CustomModifier cmod, Class cmodType)
3366 this.cmodType = cmodType;
3369 public CustomModifiedType(Type type, CustomModifier cmod, PrimitiveTypeRef cmodType)
3373 this.cmodPrimType = cmodType;
3376 internal sealed override void TypeSig(MemoryStream str)
3378 str.WriteByte(typeIndex);
3380 if (cmodType != null) {
3381 MetaData.CompressNum(cmodType.TypeDefOrRefToken(),str);
3383 MetaData.CompressNum(cmodPrimType.TypeDefOrRefToken(),str);
3391 /**************************************************************************/
3393 /// Base class for Event and Property descriptors
3396 public class Feature : MetaDataElement {
3398 internal enum MethodType : ushort { Setter = 0x01, Getter, Other = 0x04, AddOn = 0x08,
3399 RemoveOn = 0x10, Fire = 0x20 }
3401 private static readonly int INITSIZE = 5;
3402 private static readonly ushort specialName = 0x200;
3403 private static readonly ushort rtSpecialName = 0x400;
3405 protected ClassDef parent;
3406 protected ushort flags = 0;
3407 protected string name;
3408 protected int tide = 0;
3409 protected uint nameIx;
3410 protected MethodSemantics[] methods = new MethodSemantics[INITSIZE];
3412 internal Feature(string name, ClassDef par)
3418 internal void AddMethod(MethodDef meth, MethodType mType)
3420 if (tide >= methods.Length) {
3421 int len = methods.Length;
3422 MethodSemantics[] mTmp = methods;
3423 methods = new MethodSemantics[len * 2];
3424 for (int i=0; i < len; i++) {
3425 methods[i] = mTmp[i];
3428 methods[tide++] = new MethodSemantics(mType,meth,this);
3432 /// Set the specialName attribute for this Event or Property
3434 public void SetSpecialName()
3436 flags |= specialName;
3440 /// Set the RTSpecialName attribute for this Event or Property
3442 public void SetRTSpecialName()
3444 flags |= rtSpecialName;
3449 /**************************************************************************/
3451 /// Descriptor for an event
3453 public class Event : Feature {
3457 internal Event(string name, Type eType, ClassDef parent)
3458 : base(name, parent)
3461 tabIx = MDTable.Event;
3465 /// Add the addon method to this event
3467 /// <param name="addon">the addon method</param>
3468 public void AddAddon(MethodDef addon)
3470 AddMethod(addon,MethodType.AddOn);
3474 /// Add the removeon method to this event
3476 /// <param name="removeOn">the removeon method</param>
3477 public void AddRemoveOn(MethodDef removeOn)
3479 AddMethod(removeOn,MethodType.RemoveOn);
3483 /// Add the fire method to this event
3485 /// <param name="fire">the fire method</param>
3486 public void AddFire(MethodDef fire)
3488 AddMethod(fire,MethodType.Fire);
3492 /// Add another method to this event
3494 /// <param name="other">the method to be added</param>
3495 public void AddOther(MethodDef other)
3497 AddMethod(other,MethodType.Other);
3500 internal sealed override void BuildTables(MetaData md)
3503 nameIx = md.AddToStringsHeap(name);
3504 for (int i=0; i < tide; i++) {
3505 md.AddToTable(MDTable.MethodSemantics,methods[i]);
3510 internal sealed override uint Size(MetaData md)
3512 return 2 + md.StringsIndexSize() + md.CodedIndexSize(CIx.TypeDefOrRef);
3515 internal sealed override void Write(FileImage output)
3517 output.Write(flags);
3518 output.StringsIndex(nameIx);
3519 output.WriteCodedIndex(CIx.TypeDefOrRef,eventType);
3522 internal sealed override uint GetCodedIx(CIx code)
3525 case (CIx.HasCustomAttr) : return 10;
3526 case (CIx.HasSemantics) : return 0;
3533 /**************************************************************************/
3535 /// Descriptor for the Property of a class
3537 public class Property : Feature {
3539 private static readonly byte PropertyTag = 0x8;
3540 private bool instance;
3541 MethodDef getterMeth;
3542 ConstantElem constVal;
3543 uint typeBlobIx = 0;
3548 internal Property(string name, Type retType, Type[] pars, ClassDef parent) : base(name, parent)
3550 returnType = retType;
3552 if (pars != null) numPars = (uint)pars.Length;
3553 tabIx = MDTable.Property;
3557 /// Add a set method to this property
3559 /// <param name="setter">the set method</param>
3560 public void AddSetter(MethodDef setter)
3562 AddMethod(setter,MethodType.Setter);
3566 /// Add a get method to this property
3568 /// <param name="getter">the get method</param>
3569 public void AddGetter(MethodDef getter)
3571 AddMethod(getter,MethodType.Getter);
3572 getterMeth = getter;
3576 /// Add another method to this property
3578 /// <param name="other">the method</param>
3579 public void AddOther(MethodDef other)
3581 AddMethod(other,MethodType.Other);
3585 /// Add an initial value for this property
3587 /// <param name="constVal">the initial value for this property</param>
3588 public void AddInitValue(Constant constVal)
3590 this.constVal = new ConstantElem(this,constVal);
3593 public void SetInstance (bool isInstance)
3595 this.instance = isInstance;
3598 internal sealed override void BuildTables(MetaData md)
3601 nameIx = md.AddToStringsHeap(name);
3602 MemoryStream sig = new MemoryStream();
3603 byte tag = PropertyTag;
3607 MetaData.CompressNum(numPars,sig);
3608 returnType.TypeSig(sig);
3609 for (int i=0; i < numPars; i++) {
3610 parList[i].TypeSig(sig);
3612 typeBlobIx = md.AddToBlobHeap(sig.ToArray());
3613 for (int i=0; i < tide; i++) {
3614 md.AddToTable(MDTable.MethodSemantics,methods[i]);
3616 if (constVal != null) {
3617 md.AddToTable(MDTable.Constant,constVal);
3618 constVal.BuildTables(md);
3623 internal sealed override uint Size(MetaData md)
3625 return 2 + md.StringsIndexSize() + md.BlobIndexSize();
3628 internal sealed override void Write(FileImage output)
3630 output.Write(flags);
3631 output.StringsIndex(nameIx);
3632 output.BlobIndex(typeBlobIx);
3635 internal sealed override uint GetCodedIx(CIx code)
3638 case (CIx.HasCustomAttr) : return 9;
3639 case (CIx.HasConst) : return 2;
3640 case (CIx.HasSemantics) : return 1;
3647 /**************************************************************************/
3649 /// Base class for field/methods (member of a class)
3651 public abstract class Member : MetaDataElement {
3653 protected string name;
3654 protected uint nameIx = 0, sigIx = 0;
3656 internal Member(string memName)
3659 tabIx = MDTable.MemberRef;
3664 /*****************************************************************************/
3666 /// Descriptor for a field of a class
3669 public abstract class Field : Member {
3671 protected static readonly byte FieldSig = 0x6;
3673 protected Type type;
3675 internal Field(string pfName, Type pfType) : base(pfName)
3681 /**************************************************************************/
3683 /// Descriptor for a field defined in a class of THIS assembly/module
3685 public class FieldDef : Field {
3687 //private static readonly uint PInvokeImpl = 0x2000;
3688 private static readonly ushort HasFieldRVA = 0x100;
3689 private static readonly ushort HasDefault = 0x8000;
3692 ConstantElem constVal;
3694 FieldMarshal marshalInfo;
3697 internal FieldDef(string name, Type fType) : base(name,fType)
3699 tabIx = MDTable.Field;
3702 internal FieldDef(FieldAttr attrSet, string name, Type fType) : base(name, fType)
3704 flags = (ushort)attrSet;
3705 tabIx = MDTable.Field;
3709 /// Add an attribute(s) to this field
3711 /// <param name="fa">the attribute(s) to be added</param>
3712 public void AddFieldAttr(FieldAttr fa)
3714 flags |= (ushort)fa;
3718 /// Add a value for this field
3720 /// <param name="val">the value for the field</param>
3721 public void AddValue(Constant val)
3723 constVal = new ConstantElem(this,val);
3724 flags |= HasDefault;
3728 /// Add an initial value for this field (at dataLabel) (.data)
3730 /// <param name="val">the value for the field</param>
3731 /// <param name="repeatVal">the number of repetitions of this value</param>
3732 public void AddDataValue(DataConstant val)
3734 flags |= HasFieldRVA;
3735 rva = new FieldRVA(this,val);
3739 /// Set the offset of the field. Used for sequential or explicit classes.
3742 /// <param name="offs">field offset</param>
3743 public void SetOffset(uint offs)
3745 layout = new FieldLayout(this,offs);
3749 /// Set the marshalling info for a field
3751 /// <param name="mInf"></param>
3752 public void SetMarshalInfo(NativeType marshallType)
3754 flags |= (ushort) FieldAttr.HasFieldMarshal;
3755 marshalInfo = new FieldMarshal(this,marshallType);
3758 internal sealed override void BuildTables(MetaData md)
3761 nameIx = md.AddToStringsHeap(name);
3762 MemoryStream sig = new MemoryStream();
3763 sig.WriteByte(FieldSig);
3765 sigIx = md.AddToBlobHeap(sig.ToArray());
3767 md.AddToTable(MDTable.FieldRVA,rva);
3768 rva.BuildTables(md);
3769 } else if (constVal != null) {
3770 md.AddToTable(MDTable.Constant,constVal);
3771 constVal.BuildTables(md);
3773 if (layout != null) md.AddToTable(MDTable.FieldLayout,layout);
3774 if (marshalInfo != null) {
3775 md.AddToTable(MDTable.FieldMarshal,marshalInfo);
3776 marshalInfo.BuildTables(md);
3781 internal sealed override uint Size(MetaData md)
3783 return 2 + md.StringsIndexSize() + md.BlobIndexSize();
3786 internal sealed override void Write(FileImage output)
3788 output.Write(flags);
3789 output.StringsIndex(nameIx);
3790 output.BlobIndex(sigIx);
3793 internal sealed override uint GetCodedIx(CIx code)
3796 case (CIx.HasConst) : return 0;
3797 case (CIx.HasCustomAttr) : return 1;
3798 case (CIx.HasFieldMarshal) : return 0;
3799 case (CIx.MemberForwarded) : return 0;
3806 /**************************************************************************/
3808 /// Descriptor for a field of a class defined in another assembly/module
3810 public class FieldRef : Field {
3812 MetaDataElement parent;
3814 internal FieldRef(MetaDataElement paren, string name, Type fType) : base(name, fType)
3819 internal sealed override void BuildTables(MetaData md)
3822 nameIx = md.AddToStringsHeap(name);
3823 MemoryStream sig = new MemoryStream();
3824 sig.WriteByte(FieldSig);
3826 sigIx = md.AddToBlobHeap(sig.ToArray());
3830 internal sealed override uint Size(MetaData md)
3832 return md.CodedIndexSize(CIx.MemberRefParent) + md.StringsIndexSize() + md.BlobIndexSize();
3835 internal sealed override void Write(FileImage output)
3837 output.WriteCodedIndex(CIx.MemberRefParent,parent);
3838 output.StringsIndex(nameIx);
3839 output.BlobIndex(sigIx);
3842 internal sealed override uint GetCodedIx(CIx code) { return 6; }
3846 /**************************************************************************/
3848 /// Base class for Method Descriptors
3851 public abstract class Method : Member {
3853 internal Method (string methName) : base (methName)
3856 public abstract void AddCallConv(CallConv cconv);
3857 internal abstract void TypeSig(MemoryStream sig);
3858 internal abstract uint GetSigIx(MetaData md);
3861 /**************************************************************************/
3863 /// Descriptor for a method defined in THIS assembly/module
3867 public class MethodDef : Method {
3869 private static readonly ushort PInvokeImpl = 0x2000;
3870 //private static readonly uint UnmanagedExport = 0x0008;
3871 // private static readonly byte LocalSigByte = 0x7;
3872 uint parIx = 0, textOffset = 0;
3873 private CallConv callConv = CallConv.Default;
3874 private int gen_param_count;
3877 CILInstructions code;
3881 ushort methFlags = 0, implFlags = 0;
3882 int maxStack = 0, numPars = 0;
3883 bool entryPoint = false;
3885 ArrayList varArgSigList;
3886 ImplMap pinvokeImpl;
3889 internal MethodDef (MetaData md, string name, Param ret_param, Param [] pars)
3890 : this (md, 0, 0, name, ret_param, pars)
3894 internal MethodDef (MetaData md, MethAttr mAttrSet, ImplAttr iAttrSet, string name,
3895 Param ret_param, Param [] pars)
3898 methFlags = (ushort)mAttrSet;
3899 implFlags = (ushort)iAttrSet;
3900 this.ret_param = ret_param;
3903 if (parList != null)
3904 numPars = parList.Length;
3905 tabIx = MDTable.Method;
3908 internal Param[] GetPars()
3913 internal override uint GetSigIx(MetaData md)
3915 MemoryStream sig = new MemoryStream();
3917 return md.AddToBlobHeap(sig.ToArray());
3920 public override void AddCallConv(CallConv cconv)
3926 /// Add some attributes to this method descriptor
3928 /// <param name="ma">the attributes to be added</param>
3929 public void AddMethAttribute(MethAttr ma)
3931 methFlags |= (ushort)ma;
3935 /// Add some implementation attributes to this method descriptor
3937 /// <param name="ia">the attributes to be added</param>
3938 public void AddImplAttribute(ImplAttr ia)
3940 implFlags |= (ushort)ia;
3943 public void AddPInvokeInfo(ModuleRef scope, string methName,
3944 PInvokeAttr callAttr) {
3945 pinvokeImpl = new ImplMap((ushort)callAttr,this,methName,scope);
3946 methFlags |= PInvokeImpl;
3950 /// Add a named generic type parameter
3952 public GenericParameter AddGenericParameter (short index, string name)
3954 return AddGenericParameter (index, name, 0);
3958 /// Add a named generic type parameter with attributes
3960 public GenericParameter AddGenericParameter (short index, string name, GenericParamAttributes attr)
3962 GenericParameter gp = new GenericParameter (this, metaData, index, name, attr);
3963 metaData.AddToTable (MDTable.GenericParam, gp);
3969 /// Set the maximum stack height for this method
3971 /// <param name="maxStack">the maximum height of the stack</param>
3972 public void SetMaxStack(int maxStack)
3974 this.maxStack = maxStack;
3978 /// Add local variables to this method
3980 /// <param name="locals">the locals to be added</param>
3981 /// <param name="initLocals">are locals initialised to default values</param>
3982 public void AddLocals(Local[] locals, bool initLocals)
3984 this.locals = locals;
3985 this.initLocals = initLocals;
3988 /* Add Marshal info for return type */
3989 public void AddRetTypeMarshallInfo (NativeType marshallType)
3991 ret_param.AddMarshallInfo (marshallType);
3995 /// Mark this method as having an entry point
3997 public void DeclareEntryPoint()
4003 /// Create a code buffer for this method to add the IL instructions to
4005 /// <returns>a buffer for this method's IL instructions</returns>
4006 public CILInstructions CreateCodeBuffer()
4008 code = new CILInstructions(metaData);
4013 /// Make a method reference descriptor for this method to be used
4014 /// as a callsite signature for this vararg method
4016 /// <param name="optPars">the optional pars for the vararg method call</param>
4017 /// <returns></returns>
4018 public MethodRef MakeVarArgSignature(Type[] optPars)
4020 Type[] pars = new Type[numPars];
4021 MethodRef varArgSig;
4022 for (int i=0; i < numPars; i++) {
4023 pars[i] = parList[i].GetParType();
4025 varArgSig = new MethodRef (this, name, ret_param.GetParType (), pars, true, optPars, 0);
4027 if (varArgSigList == null)
4028 varArgSigList = new ArrayList ();
4029 varArgSigList.Add (varArgSig);
4033 internal sealed override void TypeSig(MemoryStream sig)
4035 sig.WriteByte((byte)callConv);
4036 if ((callConv & CallConv.Generic) == CallConv.Generic)
4037 MetaData.CompressNum ((uint) gen_param_count, sig);
4038 MetaData.CompressNum((uint)numPars,sig);
4040 ret_param.seqNo = 0;
4041 ret_param.TypeSig (sig);
4042 for (ushort i=0; i < numPars; i++) {
4043 parList[i].seqNo = (ushort)(i+1);
4044 parList[i].TypeSig(sig);
4048 internal sealed override void BuildTables(MetaData md)
4051 if (pinvokeImpl != null) {
4052 md.AddToTable(MDTable.ImplMap,pinvokeImpl);
4053 pinvokeImpl.BuildTables(md);
4055 if (entryPoint) md.SetEntryPoint(this);
4057 if (locals != null) {
4058 localSig = new LocalSig(locals);
4059 md.AddToTable(MDTable.StandAloneSig,localSig);
4060 localSig.BuildTables(md);
4061 locToken = localSig.Token();
4064 code.CheckCode(locToken,initLocals,maxStack);
4065 textOffset = md.AddCode(code);
4067 nameIx = md.AddToStringsHeap(name);
4068 sigIx = GetSigIx(md);
4069 parIx = md.TableIndex(MDTable.Param);
4070 if (ret_param.HasMarshalInfo || ret_param.HasCustomAttr) {
4071 md.AddToTable(MDTable.Param, ret_param);
4072 ret_param.BuildTables(md);
4074 for (int i=0; i < numPars; i++) {
4075 md.AddToTable(MDTable.Param,parList[i]);
4076 parList[i].BuildTables(md);
4078 if (varArgSigList != null) {
4079 foreach (MethodRef varArgSig in varArgSigList) {
4080 md.AddToTable(MDTable.MemberRef,varArgSig);
4081 varArgSig.BuildTables(md);
4084 // Console.WriteLine("method has " + numPars + " parameters");
4088 internal sealed override uint Size(MetaData md)
4090 return 8 + md.StringsIndexSize() + md.BlobIndexSize() + md.TableIndexSize(MDTable.Param);
4093 internal sealed override void Write(FileImage output)
4095 if (ZeroRva ()) output.Write(0);
4096 else output.WriteCodeRVA(textOffset);
4097 output.Write(implFlags);
4098 output.Write(methFlags);
4099 output.StringsIndex(nameIx);
4100 output.BlobIndex(sigIx);
4101 output.WriteIndex(MDTable.Param,parIx);
4104 internal bool ZeroRva ()
4106 return (((methFlags & (ushort)MethAttr.Abstract) != 0) ||
4107 ((implFlags & (ushort)ImplAttr.Runtime) != 0) ||
4108 ((implFlags & (ushort)ImplAttr.InternalCall) != 0) ||
4109 (pinvokeImpl != null)); // TODO: Not entirely true but works for now
4112 internal sealed override uint GetCodedIx(CIx code)
4115 case (CIx.HasCustomAttr) : return 0;
4116 case (CIx.HasDeclSecurity) : return 1;
4117 case (CIx.MemberRefParent) : return 3;
4118 case (CIx.MethodDefOrRef) : return 0;
4119 case (CIx.MemberForwarded) : return 1;
4120 case (CIx.CustomAttributeType) : return 2;
4121 case (CIx.TypeOrMethodDef) : return 1;
4127 /**************************************************************************/
4129 /// Descriptor for a method defined in another assembly/module
4131 public class MethodRef : Method {
4133 private static readonly byte Sentinel = 0x41;
4134 Type[] parList, optParList;
4135 MetaDataElement parent;
4136 uint numPars = 0, numOptPars = 0;
4137 CallConv callConv = CallConv.Default;
4139 int gen_param_count;
4141 internal MethodRef(MetaDataElement paren, string name, Type retType,
4142 Type[] pars, bool varArgMeth, Type[] optPars, int gen_param_count) : base(name)
4146 this.retType = retType;
4147 if (parList != null) numPars = (uint)parList.Length;
4149 optParList = optPars;
4150 if (optParList != null) numOptPars = (uint)optParList.Length;
4151 callConv = CallConv.Vararg;
4153 this.gen_param_count = gen_param_count;
4156 internal override uint GetSigIx(MetaData md)
4158 MemoryStream sig = new MemoryStream();
4160 return md.AddToBlobHeap(sig.ToArray());
4163 public override void AddCallConv(CallConv cconv)
4168 internal sealed override void TypeSig(MemoryStream sig)
4170 sig.WriteByte((byte)callConv);
4171 if ((callConv & CallConv.Generic) == CallConv.Generic)
4172 MetaData.CompressNum ((uint) gen_param_count, sig);
4173 MetaData.CompressNum(numPars+numOptPars,sig);
4174 retType.TypeSig(sig);
4175 for (int i=0; i < numPars; i++) {
4176 parList[i].TypeSig(sig);
4178 if (numOptPars > 0) {
4179 sig.WriteByte(Sentinel);
4180 for (int i=0; i < numOptPars; i++) {
4181 optParList[i].TypeSig(sig);
4186 internal sealed override void BuildTables(MetaData md)
4189 nameIx = md.AddToStringsHeap(name);
4190 sigIx = GetSigIx(md);
4194 internal sealed override uint Size(MetaData md)
4196 return md.CodedIndexSize(CIx.MemberRefParent) + md.StringsIndexSize() + md.BlobIndexSize();
4199 internal sealed override void Write(FileImage output)
4201 output.WriteCodedIndex(CIx.MemberRefParent,parent);
4202 output.StringsIndex(nameIx);
4203 output.BlobIndex(sigIx);
4206 internal sealed override uint GetCodedIx(CIx code)
4209 case (CIx.HasCustomAttr) : return 6;
4210 case (CIx.MethodDefOrRef) : return 1;
4211 case (CIx.CustomAttributeType) : return 3;
4219 /**************************************************************************/
4221 /// Descriptors for native types used for marshalling
4223 public class NativeType {
4224 public static readonly NativeType Void = new NativeType(0x01);
4225 public static readonly NativeType Boolean = new NativeType(0x02);
4226 public static readonly NativeType Int8 = new NativeType(0x03);
4227 public static readonly NativeType UInt8 = new NativeType(0x04);
4228 public static readonly NativeType Int16 = new NativeType(0x05);
4229 public static readonly NativeType UInt16 = new NativeType(0x06);
4230 public static readonly NativeType Int32 = new NativeType(0x07);
4231 public static readonly NativeType UInt32 = new NativeType(0x08);
4232 public static readonly NativeType Int64 = new NativeType(0x09);
4233 public static readonly NativeType UInt64 = new NativeType(0x0A);
4234 public static readonly NativeType Float32 = new NativeType(0x0B);
4235 public static readonly NativeType Float64 = new NativeType(0x0C);
4236 public static readonly NativeType Currency = new NativeType(0x0F);
4237 public static readonly NativeType BStr = new NativeType(0x13);
4238 public static readonly NativeType LPStr = new NativeType(0x14);
4239 public static readonly NativeType LPWStr = new NativeType(0x15);
4240 public static readonly NativeType LPTStr = new NativeType(0x16);
4241 public static readonly NativeType FixedSysString = new NativeType(0x17);
4242 public static readonly NativeType IUnknown = new NativeType(0x19);
4243 public static readonly NativeType IDispatch = new NativeType(0x1A);
4244 public static readonly NativeType Struct = new NativeType(0x1B);
4245 public static readonly NativeType Interface = new NativeType(0x1C);
4246 public static readonly NativeType Int = new NativeType(0x1F);
4247 public static readonly NativeType UInt = new NativeType(0x20);
4248 public static readonly NativeType ByValStr = new NativeType(0x22);
4249 public static readonly NativeType AnsiBStr = new NativeType(0x23);
4250 public static readonly NativeType TBstr = new NativeType(0x24);
4251 public static readonly NativeType VariantBool = new NativeType(0x25);
4252 public static readonly NativeType FuncPtr = new NativeType(0x26);
4253 public static readonly NativeType AsAny = new NativeType(0x28);
4254 public static readonly NativeType LPStruct = new NativeType(0x2b);
4255 public static readonly NativeType Error = new NativeType(0x2d);
4257 protected byte typeIndex;
4259 internal NativeType(byte tyIx) { typeIndex = tyIx; }
4260 internal byte GetTypeIndex() { return typeIndex; }
4262 internal virtual byte[] ToBlob()
4264 byte[] bytes = new byte[1];
4265 bytes[0] = GetTypeIndex();
4271 public class FixedSysString : NativeType {
4275 public FixedSysString (uint size) : base (NativeType.FixedSysString.GetTypeIndex ())
4280 internal override byte [] ToBlob ()
4282 MemoryStream str = new MemoryStream ();
4283 str.WriteByte (GetTypeIndex ());
4284 MetaData.CompressNum (size, str);
4285 return str.ToArray ();
4290 public class NativeArray : NativeType {
4292 NativeType elemType;
4293 int numElem = -1, parNum = -1, elemMult = -1;
4295 public NativeArray(NativeType elemType) : this (elemType, -1, -1, -1)
4297 this.elemType = elemType;
4300 /* public NativeArray(NativeType elemType, int len) : base(0x2A) {
4301 this.elemType = elemType;
4306 public NativeArray(NativeType elemType, int numElem, int parNumForLen, int elemMult) : base(0x2A)
4308 this.elemType = elemType;
4309 this.numElem = numElem;
4310 parNum = parNumForLen;
4311 this.elemMult = elemMult;
4314 public NativeArray(NativeType elemType, int numElem, int parNumForLen)
4315 : this (elemType, numElem, parNumForLen, -1)
4319 internal override byte[] ToBlob()
4321 MemoryStream str = new MemoryStream();
4322 str.WriteByte(GetTypeIndex());
4323 if (elemType == null) str.WriteByte(0x50); // no info (MAX)
4324 else str.WriteByte(elemType.GetTypeIndex());
4326 /* see : mono/metadata/metadata.c:mono_metadata_parse_marshal_spec
4327 * LAMESPEC: Older spec versions say elemMult comes before
4328 * len. Newer spec versions don't talk about elemMult at
4329 * all, but csc still emits it, and it is used to distinguish
4330 * between parNum being 0, and parNum being omitted.
4335 return str.ToArray ();
4337 MetaData.CompressNum((uint) parNum,str);
4338 if (numElem != -1) {
4339 MetaData.CompressNum ((uint) numElem, str);
4341 // <native_type> [ int32 ]
4342 MetaData.CompressNum((uint) elemMult,str);
4343 //else <native_type> [ int32 + int32 ]
4344 } else if (elemMult != -1) {
4345 // When can this occur ?
4346 MetaData.CompressNum (0, str);
4347 MetaData.CompressNum((uint) elemMult,str);
4349 //else <native_type> [ + int32 ]
4351 return str.ToArray();
4356 public class SafeArray : NativeType {
4358 SafeArrayType elemType;
4361 public SafeArray() : base(0x1D)
4365 public SafeArray(SafeArrayType elemType) : base(0x1D)
4367 this.elemType = elemType;
4371 internal override byte[] ToBlob()
4373 byte[] bytes = new byte[hasElemType ? 2 : 1];
4374 bytes[0] = GetTypeIndex();
4376 bytes[1] = (byte)elemType;
4382 public class FixedArray : NativeType {
4386 //public FixedArray(NativeType elemType, int numElems) : base(0x1E) {
4387 public FixedArray(int numElems) : base(0x1E)
4389 //this.elemType = elemType;
4390 numElem = (uint)numElems;
4393 internal override byte[] ToBlob()
4395 MemoryStream str = new MemoryStream();
4396 str.WriteByte(GetTypeIndex());
4397 MetaData.CompressNum(numElem,str);
4399 fixed array [5] lpstr [2]
4400 This format is not supported by ilasm 1.1.4322.2032,
4401 but is supported by 2.0.5125..
4402 ilasm 1.1 only supports "fixed array [5]"
4403 if (elemType == null) str.WriteByte(0x50); // no info (MAX)
4404 else str.WriteByte(elemType.GetTypeIndex());*/
4406 return str.ToArray();
4411 public class CustomMarshaller : NativeType {
4414 string marshallerName;
4417 public CustomMarshaller(string typeNameOrGUID, string marshallerName,
4418 string optCookie) : base(0x2C)
4420 typeName = typeNameOrGUID;
4421 this.marshallerName = marshallerName;
4425 public CustomMarshaller(string marshallerName, string optCookie)
4426 :this (null, marshallerName, optCookie)
4430 internal override byte[] ToBlob()
4432 MemoryStream str = new MemoryStream();
4433 BinaryWriter bw = new BinaryWriter(str,new UTF8Encoding());
4434 bw.Write(GetTypeIndex());
4435 //Native type name & unmanaged type - unused
4436 //See mono/metadata/metadata.c : mono_metadata_parse_marshal_spec
4437 bw.Write ((byte) 0); // Native Type name, unused
4438 bw.Write ((byte) 0); // Unmanaged type, unused
4439 if (marshallerName != null) {
4440 MetaData.CompressNum ((uint)marshallerName.Length, str);
4441 bw.Write(marshallerName.ToCharArray());
4443 bw.Write ((byte) 0);
4445 if (cookie != null) {
4446 MetaData.CompressNum ((uint)cookie.Length, str);
4447 bw.Write(cookie.ToCharArray());
4449 bw.Write ((byte) 0);
4452 return str.ToArray();
4456 /**************************************************************************/
4458 /// Descriptor for the Primitive types defined in IL
4460 public class PrimitiveType : Type {
4462 private string name;
4463 private int systemTypeIndex;
4464 public static int NumSystemTypes = 18;
4466 public static readonly PrimitiveType Void = new PrimitiveType(0x01,"Void",0);
4467 public static readonly PrimitiveType Boolean = new PrimitiveType(0x02,"Boolean",1);
4468 public static readonly PrimitiveType Char = new PrimitiveType(0x03,"Char",2);
4469 public static readonly PrimitiveType Int8 = new PrimitiveType(0x04,"SByte",3);
4470 public static readonly PrimitiveType UInt8 = new PrimitiveType(0x05,"Byte",4);
4471 public static readonly PrimitiveType Int16 = new PrimitiveType(0x06,"Int16",5);
4472 public static readonly PrimitiveType UInt16 = new PrimitiveType(0x07,"UInt16",6);
4473 public static readonly PrimitiveType Int32 = new PrimitiveType(0x08,"Int32",7);
4474 public static readonly PrimitiveType UInt32 = new PrimitiveType(0x09,"UInt32",8);
4475 public static readonly PrimitiveType Int64 = new PrimitiveType(0x0A,"Int64",9);
4476 public static readonly PrimitiveType UInt64 = new PrimitiveType(0x0B,"UInt64",10);
4477 public static readonly PrimitiveType Float32 = new PrimitiveType(0x0C,"Single",11);
4478 public static readonly PrimitiveType Float64 = new PrimitiveType(0x0D,"Double",12);
4479 public static readonly PrimitiveType String = new PrimitiveType(0x0E,"String",13);
4480 internal static readonly PrimitiveType Class = new PrimitiveType(0x12);
4481 internal static readonly PrimitiveType Var = new PrimitiveType(0x13);
4482 internal static readonly PrimitiveType GenericInst = new PrimitiveType(0x15);
4483 public static readonly PrimitiveType TypedRef = new PrimitiveType(0x16,"TypedReference",14);
4484 public static readonly PrimitiveType IntPtr = new PrimitiveType(0x18,"IntPtr",15);
4485 public static readonly PrimitiveType UIntPtr = new PrimitiveType(0x19,"UIntPtr",16);
4486 public static readonly PrimitiveType Object = new PrimitiveType(0x1C,"Object",17);
4487 internal static readonly PrimitiveType ClassType = new PrimitiveType(0x50);
4488 internal static readonly PrimitiveType SZArray = new PrimitiveType(0x1D);
4489 internal static readonly PrimitiveType MVar = new PrimitiveType(0x1E);
4490 internal static readonly PrimitiveType ValueType = new PrimitiveType(0x11, "ValueType", 18);
4491 public static readonly PrimitiveType NativeInt = IntPtr;
4492 public static readonly PrimitiveType NativeUInt = UIntPtr;
4494 internal PrimitiveType(byte typeIx) : base(typeIx) { }
4496 internal PrimitiveType(byte typeIx, string name, int STIx) : base(typeIx)
4499 this.systemTypeIndex = STIx;
4502 internal string GetName() { return name; }
4504 internal int GetSystemTypeIx() { return systemTypeIndex; }
4506 internal sealed override void TypeSig(MemoryStream str)
4508 str.WriteByte(typeIndex);
4511 internal override MetaDataElement GetTypeSpec(MetaData md)
4513 TypeSpec tS = md.GetPrimitiveTypeSpec(systemTypeIndex);
4515 tS = new TypeSpec(this,md);
4516 md.SetPrimitiveTypeSpec(systemTypeIndex,tS);
4517 md.AddToTable(MDTable.TypeSpec,tS);
4524 public class PrimitiveTypeRef : Type
4529 internal PrimitiveTypeRef(PrimitiveType type, MetaData md)
4536 internal uint TypeDefOrRefToken()
4538 uint cIx = type.GetTypeSpec (metaData).Row;
4539 cIx = (cIx << 2) | 0x2;
4544 /**************************************************************************/
4546 /// Descriptor for an pointer (type * or type &)
4548 public abstract class PtrType : Type {
4552 internal PtrType(Type bType, byte typeIx) : base(typeIx)
4555 tabIx = MDTable.TypeSpec;
4558 internal sealed override void TypeSig(MemoryStream str)
4560 str.WriteByte(typeIndex);
4561 baseType.TypeSig(str);
4565 /**************************************************************************/
4567 /// Descriptor for a managed pointer (type & or byref)
4570 public class ManagedPointer : PtrType {
4573 /// Create new managed pointer to baseType
4575 /// <param name="bType">the base type of the pointer</param>
4576 public ManagedPointer(Type baseType) : base(baseType,0x10) { }
4579 /**************************************************************************/
4581 /// Descriptor for an unmanaged pointer (type *)
4583 public class UnmanagedPointer : PtrType {
4586 /// Create a new unmanaged pointer to baseType
4588 /// <param name="baseType">the base type of the pointer</param>
4589 public UnmanagedPointer(Type baseType) : base(baseType, 0x0F) { }
4593 /**************************************************************************/
4595 public interface IExternRef {
4596 ClassRef AddClass(string nsName, string name);
4597 ClassRef AddValueClass(string nsName, string name);
4601 /// A reference to an external assembly (.assembly extern)
4603 public class AssemblyRef : ResolutionScope, IExternRef {
4605 private ushort major, minor, build, revision;
4606 uint flags, keyIx, hashIx, cultIx;
4607 bool hasVersion = false, isKeyToken = false;
4611 internal AssemblyRef(MetaData md, string name) : base(name,md)
4613 tabIx = MDTable.AssemblyRef;
4616 public void AddAssemblyAttr (AssemAttr aa)
4622 /// Add version information about this external assembly
4624 /// <param name="majVer">Major Version</param>
4625 /// <param name="minVer">Minor Version</param>
4626 /// <param name="bldNo">Build Number</param>
4627 /// <param name="revNo">Revision Number</param>
4628 public void AddVersionInfo(int majVer, int minVer, int bldNo, int revNo)
4630 major = (ushort)majVer;
4631 minor = (ushort)minVer;
4632 build = (ushort)bldNo;
4633 revision = (ushort)revNo;
4638 /// Add the hash value for this external assembly
4640 /// <param name="hash">bytes of the hash value</param>
4641 public void AddHash(byte[] hash)
4643 hashIx = metaData.AddToBlobHeap(hash);
4647 /// Set the culture for this external assembly
4649 /// <param name="cult">the culture string</param>
4650 public void AddCulture(string cult)
4652 cultIx = metaData.AddToStringsHeap(cult);
4657 /// Add the full public key for this external assembly
4659 /// <param name="key">bytes of the public key</param>
4660 public void AddKey(byte[] key)
4662 flags |= 0x0001; // full public key
4664 keyIx = metaData.AddToBlobHeap(key);
4668 /// Add the public key token (low 8 bytes of the public key)
4670 /// <param name="key">low 8 bytes of public key</param>
4671 public void AddKeyToken(byte[] key)
4673 keyIx = metaData.AddToBlobHeap(key);
4679 /// Add a class to this external assembly
4681 /// <param name="nsName">name space name</param>
4682 /// <param name="name">class name</param>
4683 /// <returns></returns>
4684 public virtual ClassRef AddClass(string nsName, string name)
4686 ClassRef aClass = new ClassRef(nsName,name,metaData);
4687 metaData.AddToTable(MDTable.TypeRef,aClass);
4688 aClass.SetParent(this);
4693 /// Add a value class to this external assembly
4695 /// <param name="nsName">name space name</param>
4696 /// <param name="name">class name</param>
4697 /// <returns></returns>
4698 public virtual ClassRef AddValueClass(string nsName, string name)
4700 ClassRef aClass = new ClassRef(nsName,name,metaData);
4701 metaData.AddToTable(MDTable.TypeRef,aClass);
4702 aClass.SetParent(this);
4703 aClass.MakeValueClass(ValueClass.ValueType);
4707 internal string TypeName()
4709 string result = name;
4711 result = result + ", Version=" + major + "." + minor + "." +
4712 build + "." + revision;
4713 if (keyBytes != null) {
4714 string tokenStr = "=";
4715 if (isKeyToken) tokenStr = "Token=";
4716 result = result + ", PublicKey" + tokenStr;
4717 for (int i=0; i < keyBytes.Length; i++) {
4718 result = result + Hex.Byte(keyBytes[i]);
4721 if (culture != null)
4722 result = result + ", Culture=" + culture;
4726 internal sealed override uint Size(MetaData md)
4728 return 12 + 2 * md.StringsIndexSize() + 2 * md.BlobIndexSize();
4731 internal sealed override void Write(FileImage output)
4733 output.Write(major);
4734 output.Write(minor);
4735 output.Write(build);
4736 output.Write(revision);
4737 output.Write(flags);
4738 output.BlobIndex(keyIx);
4739 output.StringsIndex(nameIx);
4740 output.StringsIndex(cultIx);
4741 output.BlobIndex(hashIx);
4744 internal sealed override uint GetCodedIx(CIx code)
4747 case (CIx.ResolutionScope) : return 2;
4748 case (CIx.HasCustomAttr) : return 15;
4749 case (CIx.Implementation) : return 1;
4756 /**************************************************************************/
4758 /// Descriptor for a class defined in System (mscorlib)
4760 internal class SystemClass : ClassRef {
4762 PrimitiveType elemType;
4764 internal SystemClass(PrimitiveType eType, AssemblyRef paren, MetaData md)
4765 : base("System",eType.GetName(),md) {
4770 internal override sealed MetaDataElement GetTypeSpec(MetaData md)
4772 if (typeSpec == null) typeSpec = (TypeSpec)elemType.GetTypeSpec(md);
4777 internal sealed override void TypeSig(MemoryStream str)
4779 str.WriteByte(elemType.GetTypeIndex());
4784 /**************************************************************************/
4786 /// The assembly for mscorlib.
4788 public sealed class MSCorLib : AssemblyRef {
4790 private static readonly int valueTypeIx = 18;
4791 private readonly string systemName = "System";
4792 private Class[] systemClasses = new Class[valueTypeIx+2];
4793 private PrimitiveType[] systemTypes = new PrimitiveType[valueTypeIx];
4795 private static int[] specialNames = {
4796 PrimitiveType.Void.GetName().GetHashCode(),
4797 PrimitiveType.Boolean.GetName().GetHashCode(),
4798 PrimitiveType.Char.GetName().GetHashCode(),
4799 PrimitiveType.Int8.GetName().GetHashCode(),
4800 PrimitiveType.UInt8.GetName().GetHashCode(),
4801 PrimitiveType.Int16.GetName().GetHashCode(),
4802 PrimitiveType.UInt16.GetName().GetHashCode(),
4803 PrimitiveType.Int32.GetName().GetHashCode(),
4804 PrimitiveType.UInt32.GetName().GetHashCode(),
4805 PrimitiveType.Int64.GetName().GetHashCode(),
4806 PrimitiveType.UInt64.GetName().GetHashCode(),
4807 PrimitiveType.Float32.GetName().GetHashCode(),
4808 PrimitiveType.Float64.GetName().GetHashCode(),
4809 PrimitiveType.String.GetName().GetHashCode(),
4810 PrimitiveType.TypedRef.GetName().GetHashCode(),
4811 PrimitiveType.IntPtr.GetName().GetHashCode(),
4812 PrimitiveType.UIntPtr.GetName().GetHashCode(),
4813 PrimitiveType.Object.GetName().GetHashCode(),
4814 PrimitiveType.ValueType.GetName ().GetHashCode(),
4815 "Enum".GetHashCode()
4818 internal MSCorLib(MetaData md) : base(md,"mscorlib")
4820 if (!PEFile.IsMSCorlib)
4821 md.AddToTable(MDTable.AssemblyRef,this);
4822 systemTypes[PrimitiveType.Void.GetSystemTypeIx()] = PrimitiveType.Void;
4823 systemTypes[PrimitiveType.Boolean.GetSystemTypeIx()] = PrimitiveType.Boolean;
4824 systemTypes[PrimitiveType.Char.GetSystemTypeIx()] = PrimitiveType.Char;
4825 systemTypes[PrimitiveType.Int8.GetSystemTypeIx()] = PrimitiveType.Int8;
4826 systemTypes[PrimitiveType.UInt8.GetSystemTypeIx()] = PrimitiveType.UInt8;
4827 systemTypes[PrimitiveType.Int16.GetSystemTypeIx()] = PrimitiveType.Int16;
4828 systemTypes[PrimitiveType.UInt16.GetSystemTypeIx()] = PrimitiveType.UInt16;
4829 systemTypes[PrimitiveType.Int32.GetSystemTypeIx()] = PrimitiveType.Int32;
4830 systemTypes[PrimitiveType.UInt32.GetSystemTypeIx()] = PrimitiveType.UInt32;
4831 systemTypes[PrimitiveType.Int64.GetSystemTypeIx()] = PrimitiveType.Int64;
4832 systemTypes[PrimitiveType.UInt64.GetSystemTypeIx()] = PrimitiveType.UInt64;
4833 systemTypes[PrimitiveType.Float32.GetSystemTypeIx()] = PrimitiveType.Float32;
4834 systemTypes[PrimitiveType.Float64.GetSystemTypeIx()] = PrimitiveType.Float64;
4835 systemTypes[PrimitiveType.IntPtr.GetSystemTypeIx()] = PrimitiveType.IntPtr;
4836 systemTypes[PrimitiveType.UIntPtr.GetSystemTypeIx()] = PrimitiveType.UIntPtr;
4837 systemTypes[PrimitiveType.String.GetSystemTypeIx()] = PrimitiveType.String;
4838 systemTypes[PrimitiveType.Object.GetSystemTypeIx()] = PrimitiveType.Object;
4839 systemTypes[PrimitiveType.TypedRef.GetSystemTypeIx()] = PrimitiveType.TypedRef;
4843 /// Add a class to the mscorlib assembly
4845 /// <param name="nsName">name space name</param>
4846 /// <param name="name">class name</param>
4847 /// <returns></returns>
4848 public override ClassRef AddClass(string nsName, string name)
4850 /* This gets called by !mscorlib, for adding references INTO mscorlib, so
4851 it should be returning ClassRef ..*/
4852 Class aClass = GetSpecialClass(nsName,name);
4853 if (aClass == null) {
4854 aClass = new ClassRef(nsName,name,metaData);
4855 metaData.AddToTable(MDTable.TypeRef,aClass);
4856 if (aClass is ClassRef)
4857 ((ClassRef) aClass).SetParent(this);
4859 //FIXME: Check for !ClassRef here?
4860 return (ClassRef) aClass;
4863 private Class GetSpecialClass(string nsName,string name)
4865 if (nsName.CompareTo(systemName) != 0) return null;
4866 int hash = name.GetHashCode();
4867 for (int i=0; i < specialNames.Length; i++) {
4868 if (hash != specialNames[i])
4870 if (systemClasses[i] == null) {
4871 if (i < valueTypeIx) {
4872 systemClasses[i] = new SystemClass(systemTypes[i],this,metaData);
4873 if ((systemTypes[i] != PrimitiveType.Object) &&
4874 (systemTypes[i] != PrimitiveType.String)) {
4875 systemClasses[i].MakeValueClass(ValueClass.ValueType);
4878 systemClasses[i] = new ClassRef(nsName,name,metaData);
4879 ((ClassRef) systemClasses[i]).SetParent(this);
4880 if (!ClassDef.IsValueType (nsName, name) && !ClassDef.IsEnum (nsName, name))
4881 systemClasses[i].MakeValueClass(ValueClass.ValueType);
4883 metaData.AddToTable(MDTable.TypeRef,systemClasses[i]);
4885 return systemClasses[i];
4890 internal void SetSpecialSystemClass (string nsName, string name, Class aClass)
4892 if (nsName != systemName) return;
4893 int hash = name.GetHashCode ();
4894 for (int i = 0; i < specialNames.Length; i++) {
4895 if (hash != specialNames [i])
4897 if (systemClasses [i] == null) {
4898 systemClasses [i] = aClass;
4903 internal Class GetSpecialSystemClass(PrimitiveType pType)
4905 int ix = pType.GetSystemTypeIx();
4906 if (systemClasses[ix] == null && !PEFile.IsMSCorlib) {
4907 systemClasses[ix] = new SystemClass(pType,this,metaData);
4908 metaData.AddToTable(MDTable.TypeRef,systemClasses[ix]);
4910 return systemClasses[ix];
4913 private ClassRef GetValueClass(string name, int hash)
4915 /* Called by MSCorLib.AddValueClass, which is called by
4916 !mscorlib, for adding ref to value class INTO mscorlib,
4917 so this should be classref */
4918 int ix = valueTypeIx;
4919 if (hash != specialNames[valueTypeIx]) ix++;
4920 if (systemClasses[ix] == null) {
4921 systemClasses[ix] = new ClassRef(systemName,name,metaData);
4922 ((ClassRef) systemClasses[ix]).SetParent(this);
4923 ((ClassRef) systemClasses[ix]).MakeValueClass(ValueClass.ValueType);
4924 metaData.AddToTable(MDTable.TypeRef,systemClasses[ix]);
4926 return (ClassRef) systemClasses[ix];
4929 internal Class ValueType()
4931 if (systemClasses[valueTypeIx] == null && !PEFile.IsMSCorlib) {
4932 ClassRef valType = new ClassRef("System","ValueType",metaData);
4933 valType.SetParent(this);
4934 valType.MakeValueClass(ValueClass.ValueType);
4935 metaData.AddToTable(MDTable.TypeRef,valType);
4936 systemClasses[valueTypeIx] = valType;
4938 return systemClasses[valueTypeIx];
4941 internal Class EnumType()
4943 /* Called by both mscorlib & !mscorlib, so can be
4944 either ClassRef or ClassDef */
4945 //systemClasses [ valueTypeIx + 1] -> System.Enum
4946 if (systemClasses[valueTypeIx + 1] == null && !PEFile.IsMSCorlib) {
4947 ClassRef valType = new ClassRef("System","Enum",metaData);
4948 valType.SetParent(this);
4949 valType.MakeValueClass(ValueClass.Enum);
4950 metaData.AddToTable(MDTable.TypeRef,valType);
4951 systemClasses[valueTypeIx + 1] = valType;
4953 return systemClasses[valueTypeIx + 1];
4957 /// Add a value class to this external assembly
4959 /// <param name="nsName">name space name</param>
4960 /// <param name="name">class name</param>
4961 /// <returns></returns>
4962 public override ClassRef AddValueClass(string nsName, string name)
4964 if (nsName.CompareTo(systemName) == 0) {
4965 int hash = name.GetHashCode();
4966 if ((hash == specialNames[valueTypeIx]) ||
4967 (hash == specialNames[valueTypeIx+1])) {
4968 return GetValueClass(name,hash);
4971 ClassRef aClass = new ClassRef(nsName,name,metaData);
4972 metaData.AddToTable(MDTable.TypeRef,aClass);
4973 aClass.SetParent(this);
4974 aClass.MakeValueClass(ValueClass.ValueType);
4980 /**************************************************************************/
4983 /// Root (20 bytes + UTF-8 Version String + quad align padding)
4984 /// StreamHeaders (8 bytes + null terminated name string + quad align padding)
4986 /// #~ (always present - holds metadata tables)
4987 /// #Strings (always present - holds identifier strings)
4988 /// #US (Userstring heap)
4989 /// #Blob (signature blobs)
4990 /// #GUID (guids for assemblies or Modules)
4992 public class MetaData {
4994 internal static readonly int[] CIxShiftMap = {2,2,5,1,2,3,1,1,1,2,3,2,1};
4995 private static readonly byte StringsHeapMask = 0x1;
4996 private static readonly byte GUIDHeapMask = 0x2;
4997 private static readonly byte BlobHeapMask = 0x4;
4998 private static readonly uint MetaDataSignature = 0x424A5342;
4999 private static readonly uint maxSmlIxSize = 0xFFFF;
5000 private static readonly uint max1BitSmlIx = 0x7FFF;
5001 private static readonly uint max2BitSmlIx = 0x3FFF;
5002 private static readonly uint max3BitSmlIx = 0x1FFF;
5003 private static readonly uint max5BitSmlIx = 0x7FF;
5004 // NOTE: version and stream name strings MUST always be quad padded
5005 private static readonly string version = "v4.0.30319\0\0";
5006 private static readonly char[] tildeName = {'#','~','\0','\0'};
5007 private static readonly char[] stringsName = {'#','S','t','r','i','n','g','s','\0','\0','\0','\0'};
5008 private static readonly char[] usName = {'#','U','S','\0'};
5009 private static readonly char[] guidName = {'#','G','U','I','D','\0','\0','\0'};
5010 private static readonly char[] blobName = {'#','B','l','o','b','\0','\0','\0'};
5011 private static readonly uint MetaDataHeaderSize = 20 + (uint)version.Length;
5012 private static readonly uint TildeHeaderSize = 24;
5013 private static readonly uint StreamHeaderSize = 8;
5014 private static readonly uint numMetaDataTables = (int)MDTable.GenericParamConstraint + 1;
5016 MetaDataStream strings, us, guid, blob;
5018 MetaDataStream[] streams = new MetaDataStream[5];
5019 uint numStreams = 5;
5020 uint tildeTide = 0, tildePadding = 0, tildeStart = 0;
5021 uint numTables = 0, resourcesSize = 0;
5022 ArrayList[] metaDataTables = new ArrayList[numMetaDataTables];
5023 ArrayList byteCodes = new ArrayList();
5024 uint codeSize = 0, codeStart, byteCodePadding = 0, metaDataSize = 0;
5025 ulong valid = 0, /*sorted = 0x000002003301FA00;*/ sorted = 0;
5026 bool[] largeIx = new bool[numMetaDataTables];
5027 bool[] lgeCIx = new bool[(int)CIx.MaxCIx];
5028 bool largeStrings = false, largeUS = false, largeGUID = false, largeBlob = false;
5029 private FileImage file;
5030 private byte heapSizes = 0;
5031 MetaDataElement entryPoint;
5032 BinaryWriter output;
5033 public MSCorLib mscorlib;
5034 private TypeSpec[] systemTypeSpecs = new TypeSpec[PrimitiveType.NumSystemTypes];
5036 private ArrayList cattr_list;
5037 private ArrayList declsec_list;
5038 ArrayList resources;
5040 internal MetaData(FileImage file)
5042 // tilde = new MetaDataStream(tildeName,false,0);
5044 strings = new MetaDataStream(stringsName,new UTF8Encoding(),true);
5045 us = new MetaDataStream(usName,new UnicodeEncoding(),true);
5046 guid = new MetaDataStream(guidName,false);
5047 blob = new MetaDataStream(blobName,true);
5048 streams[1] = strings;
5052 for (int i=0; i < numMetaDataTables; i++) {
5055 for (int i=0; i < lgeCIx.Length; i++) {
5058 mscorlib = new MSCorLib(this);
5061 internal TypeSpec GetPrimitiveTypeSpec(int ix)
5063 return systemTypeSpecs[ix];
5066 internal void SetPrimitiveTypeSpec(int ix, TypeSpec typeSpec)
5068 systemTypeSpecs[ix] = typeSpec;
5071 internal uint Size()
5073 return metaDataSize;
5076 private void CalcHeapSizes ()
5078 if (strings.LargeIx()) {
5079 largeStrings = true;
5080 heapSizes |= StringsHeapMask;
5082 if (guid.LargeIx()) {
5084 heapSizes |= GUIDHeapMask;
5086 if (blob.LargeIx()) {
5088 heapSizes |= BlobHeapMask;
5091 largeUS = us.LargeIx();
5094 internal void StreamSize(byte mask)
5099 internal uint AddToUSHeap(string str)
5101 if (str == null) return 0;
5102 return us.Add(str,true);
5105 internal uint AddToUSHeap(byte[] str)
5107 if (str == null) return 0;
5108 return us.Add (str, true);
5111 internal uint AddToStringsHeap(string str)
5113 if ((str == null) || (str.CompareTo("") == 0)) return 0;
5114 return strings.Add(str,false);
5117 internal uint AddToGUIDHeap(Guid guidNum)
5119 return guid.Add(guidNum, false);
5122 internal uint AddToBlobHeap(byte[] blobBytes)
5124 if (blobBytes == null) return 0;
5125 return blob.Add(blobBytes, true);
5128 internal uint AddToBlobHeap(byte val)
5130 return blob.Add(val, true);
5133 internal uint AddToBlobHeap(sbyte val)
5135 return blob.Add(val, true);
5138 internal uint AddToBlobHeap(ushort val)
5140 return blob.Add(val, true);
5143 internal uint AddToBlobHeap(short val)
5145 return blob.Add(val, true);
5148 internal uint AddToBlobHeap(uint val)
5150 return blob.Add(val, true);
5153 internal uint AddToBlobHeap(int val)
5155 return blob.Add(val, true);
5158 internal uint AddToBlobHeap(ulong val)
5160 return blob.Add(val, true);
5163 internal uint AddToBlobHeap(long val)
5165 return blob.Add(val, true);
5168 internal uint AddToBlobHeap(float val)
5170 return blob.Add(val, true);
5173 internal uint AddToBlobHeap(double val)
5175 return blob.Add(val, true);
5178 internal uint AddToBlobHeap(string val)
5180 return blob.Add(val,true);
5183 internal void AddCustomAttribute (CustomAttribute cattr)
5185 if (cattr_list == null)
5186 cattr_list = new ArrayList ();
5187 cattr_list.Add (cattr);
5190 internal void AddDeclSecurity (BaseDeclSecurity decl_sec)
5192 if (declsec_list == null)
5193 declsec_list = new ArrayList ();
5194 declsec_list.Add (decl_sec);
5197 private ArrayList GetTable(MDTable tableIx)
5199 int tabIx = (int)tableIx;
5200 if (metaDataTables[tabIx] == null) {
5201 metaDataTables[tabIx] = new ArrayList();
5202 valid |= ((ulong)0x1 << tabIx);
5203 // Console.WriteLine("after creating table " + tableIx + "(" + tabIx + ") valid = " + valid);
5206 return metaDataTables[tabIx];
5209 internal void AddToTable(MDTable tableIx, MetaDataElement elem)
5212 // Console.Out.WriteLine("ERROR - element already in table " + tableIx);
5215 // updates Row field of the element
5216 // Console.WriteLine("Adding element to table " + (uint)tableIx);
5217 ArrayList table = GetTable(tableIx);
5218 elem.Row = (uint)table.Count + 1;
5222 internal uint TableIndex(MDTable tableIx)
5224 if (metaDataTables[(int)tableIx] == null) return 1;
5225 return (uint)metaDataTables[(int)tableIx].Count+1;
5228 internal uint AddCode(CILInstructions byteCode)
5230 byteCodes.Add(byteCode);
5231 uint offset = codeSize + codeStart;
5232 codeSize += byteCode.GetCodeSize();
5236 internal void SetEntryPoint(MetaDataElement ep)
5241 internal uint AddResource(byte[] resBytes)
5243 if (resources == null) resources = new ArrayList ();
5244 resources.Add (resBytes);
5245 uint offset = resourcesSize;
5246 resourcesSize += (uint)resBytes.Length + 4;
5250 internal void AddData(DataConstant cVal)
5252 file.AddInitData(cVal);
5255 internal static void CompressNum(uint val, MemoryStream sig)
5258 sig.WriteByte((byte)val);
5259 } else if (val <= 0x3FFF) {
5260 byte b1 = (byte)((val >> 8) | 0x80);
5261 byte b2 = (byte)(val & FileImage.iByteMask[0]);
5265 byte b1 = (byte)((val >> 24) | 0xC0);
5266 byte b2 = (byte)((val & FileImage.iByteMask[2]) >> 16);
5267 byte b3 = (byte)((val & FileImage.iByteMask[1]) >> 8);;
5268 byte b4 = (byte)(val & FileImage.iByteMask[0]);
5276 internal uint CodeSize()
5278 return codeSize + byteCodePadding;
5281 internal uint GetResourcesSize()
5283 return resourcesSize;
5286 internal uint StringsIndexSize()
5288 if (largeStrings) return 4;
5292 internal uint GUIDIndexSize()
5294 if (largeGUID) return 4;
5298 internal uint USIndexSize()
5300 if (largeUS) return 4;
5304 internal uint BlobIndexSize()
5306 if (largeBlob) return 4;
5310 internal uint CodedIndexSize(CIx code)
5312 if (lgeCIx[(uint)code]) return 4;
5316 internal uint TableIndexSize(MDTable tabIx)
5318 if (largeIx[(uint)tabIx]) return 4;
5322 private void SetIndexSizes()
5324 for (int i=0; i < numMetaDataTables; i++) {
5325 if (metaDataTables[i] == null)
5328 uint count = (uint)metaDataTables[i].Count;
5329 if (count > maxSmlIxSize)
5332 MDTable tabIx = (MDTable)i;
5333 if (count > max5BitSmlIx) {
5334 lgeCIx[(int)CIx.HasCustomAttr] = true;
5336 if (count > max3BitSmlIx) {
5337 if ((tabIx == MDTable.TypeRef) || (tabIx == MDTable.ModuleRef) || (tabIx == MDTable.Method) || (tabIx == MDTable.TypeSpec) || (tabIx == MDTable.Field))
5338 lgeCIx[(int)CIx.CustomAttributeType] = true;
5339 if ((tabIx == MDTable.Method) || (tabIx == MDTable.MemberRef))
5340 lgeCIx[(int)CIx.MemberRefParent] = true;
5342 if (count > max2BitSmlIx) {
5343 if ((tabIx == MDTable.Field) || (tabIx == MDTable.Param) || (tabIx == MDTable.Property))
5344 lgeCIx[(int)CIx.HasConst] = true;
5345 if ((tabIx == MDTable.TypeDef) || (tabIx == MDTable.TypeRef) || (tabIx == MDTable.TypeSpec))
5346 lgeCIx[(int)CIx.TypeDefOrRef] = true;
5347 if ((tabIx == MDTable.TypeDef) || (tabIx == MDTable.Method) || (tabIx == MDTable.Assembly))
5348 lgeCIx[(int)CIx.HasDeclSecurity] = true;
5349 if ((tabIx == MDTable.File) || (tabIx == MDTable.AssemblyRef) || (tabIx == MDTable.ExportedType))
5350 lgeCIx[(int)CIx.Implementation] = true;
5351 if ((tabIx == MDTable.Module) || (tabIx == MDTable.ModuleRef) || (tabIx == MDTable.AssemblyRef) || (tabIx == MDTable.TypeRef))
5352 lgeCIx[(int)CIx.ResolutionScope] = true;
5354 if (count > max1BitSmlIx) {
5355 if ((tabIx == MDTable.Field) || (tabIx == MDTable.Param))
5356 lgeCIx[(int)CIx.HasFieldMarshal] = true;
5357 if ((tabIx == MDTable.Event) || (tabIx == MDTable.Property))
5358 lgeCIx[(int)CIx.HasSemantics] = true;
5359 if ((tabIx == MDTable.Method) || (tabIx == MDTable.MemberRef))
5360 lgeCIx[(int)CIx.MethodDefOrRef] = true;
5361 if ((tabIx == MDTable.Field) || (tabIx == MDTable.Method))
5362 lgeCIx[(int)CIx.MemberForwarded] = true;
5363 if ((tabIx == MDTable.TypeDef) || (tabIx == MDTable.Method))
5364 lgeCIx[(int)CIx.TypeOrMethodDef] = true;
5369 private void SetStreamOffsets()
5371 uint sizeOfHeaders = StreamHeaderSize + (uint)tildeName.Length;
5372 for (int i=1; i < numStreams; i++) {
5373 sizeOfHeaders += streams[i].headerSize();
5375 metaDataSize = MetaDataHeaderSize + sizeOfHeaders;
5376 tildeStart = metaDataSize;
5377 metaDataSize += tildeTide + tildePadding;
5378 for (int i=1; i < numStreams; i++) {
5379 streams[i].Start = metaDataSize;
5380 metaDataSize += streams[i].Size();
5381 streams[i].WriteDetails();
5385 internal void CalcTildeStreamSize()
5388 //tilde.SetIndexSizes(strings.LargeIx(),us.LargeIx(),guid.LargeIx(),blob.LargeIx());
5389 tildeTide = TildeHeaderSize;
5390 tildeTide += 4 * numTables;
5391 //Console.WriteLine("Tilde header + sizes = " + tildeTide);
5392 for (int i=0; i < numMetaDataTables; i++) {
5393 if (metaDataTables[i] != null) {
5394 ArrayList table = metaDataTables[i];
5395 // Console.WriteLine("Meta data table " + i + " at offset " + tildeTide);
5396 tildeTide += (uint)table.Count * ((MetaDataElement)table[0]).Size(this);
5397 // Console.WriteLine("Metadata table " + i + " has size " + table.Count);
5398 // Console.WriteLine("tildeTide = " + tildeTide);
5401 if ((tildeTide % 4) != 0) tildePadding = 4 - (tildeTide % 4);
5402 //Console.WriteLine("tildePadding = " + tildePadding);
5405 internal void WriteTildeStream(FileImage output)
5407 output.Seek(0,SeekOrigin.Current);
5408 output.Write((uint)0); // Reserved
5409 output.Write((byte)2); // MajorVersion
5410 output.Write((byte)0); // MinorVersion
5411 output.Write(heapSizes);
5412 output.Write((byte)1); // Reserved
5413 output.Write(valid);
5414 output.Write(sorted);
5416 for (int i=0; i < numMetaDataTables; i++) {
5417 if (metaDataTables[i] != null) {
5418 uint count = (uint)metaDataTables[i].Count;
5419 output.Write(count);
5423 output.Seek(0,SeekOrigin.Current);
5424 // Console.WriteLine("Starting metaData tables at " + tabStart);
5425 for (int i=0; i < numMetaDataTables; i++) {
5426 if (metaDataTables[i] != null) {
5427 // Console.WriteLine("Starting metaData table " + i + " at " + (output.Seek(0,SeekOrigin.Current) - startTilde));
5428 ArrayList table = metaDataTables[i];
5429 for (int j=0; j < table.Count; j++) {
5430 ((MetaDataElement)table[j]).Write(output);
5434 // Console.WriteLine("Writing padding at " + output.Seek(0,SeekOrigin.Current));
5435 for (int i=0; i < tildePadding; i++) output.Write((byte)0);
5438 private void BuildTable(ArrayList table)
5440 if (table == null) return;
5441 for (int j=0; j < table.Count; j++) {
5442 ((MetaDataElement)table[j]).BuildTables(this);
5446 private void SortTable (ArrayList mTable)
5448 if (mTable == null) return;
5450 for (int i=0; i < mTable.Count; i++) {
5451 ((MetaDataElement)mTable[i]).Row = (uint)i+1;
5455 internal void BuildMetaData(uint codeStartOffset)
5457 codeStart = codeStartOffset;
5458 BuildTable(metaDataTables[(int)MDTable.TypeDef]);
5459 BuildTable(metaDataTables[(int)MDTable.TypeSpec]);
5460 BuildTable(metaDataTables[(int)MDTable.MemberRef]);
5461 BuildTable(metaDataTables[(int)MDTable.GenericParam]);
5462 BuildTable(metaDataTables[(int)MDTable.MethodSpec]);
5463 BuildTable(metaDataTables[(int)MDTable.GenericParamConstraint]);
5464 BuildTable(metaDataTables[(int)MDTable.ManifestResource]);
5466 if (cattr_list != null) {
5467 foreach (CustomAttribute cattr in cattr_list)
5468 cattr.BuildTables (this);
5471 if (declsec_list != null) {
5472 foreach (BaseDeclSecurity decl_sec in declsec_list)
5473 decl_sec.BuildTables (this);
5476 /* for (int i=0; i < metaDataTables.Length; i++) {
5477 ArrayList table = metaDataTables[i];
5478 if (table != null) {
5479 for (int j=0; j < table.Count; j++) {
5480 ((MetaDataElement)table[j]).BuildTables(this);
5487 for (int i=1; i < numStreams; i++) {
5488 streams[i].EndStream();
5490 CalcTildeStreamSize();
5492 byteCodePadding = NumToAlign(codeSize,4);
5493 if (entryPoint != null) file.SetEntryPoint(entryPoint.Token());
5495 // Check ordering of specific tables
5496 // Constant, CustomAttribute, FieldMarshal, DeclSecurity, MethodSemantics
5497 // ImplMap, GenericParam
5498 // Need to load GenericParamConstraint AFTER GenericParam table in correct order
5500 // InterfaceImpl, ClassLayout, FieldLayout, MethodImpl, FieldRVA, NestedClass
5501 // will _ALWAYS_ be in the correct order as embedded in BuildMDTables
5503 SortTable(metaDataTables[(int)MDTable.Constant]);
5504 SortTable(metaDataTables[(int)MDTable.FieldMarshal]);
5505 SortTable(metaDataTables[(int)MDTable.DeclSecurity]);
5506 SortTable(metaDataTables[(int)MDTable.MethodSemantics]);
5507 SortTable(metaDataTables[(int)MDTable.ImplMap]);
5508 if (metaDataTables[(int)MDTable.GenericParam] != null) {
5509 SortTable(metaDataTables[(int)MDTable.GenericParam]);
5510 // Now add GenericParamConstraints
5511 /*for (int i=0; i < metaDataTables[(int)MDTable.GenericParam].Count; i++) {
5512 ((GenericParameter)metaDataTables[(int)MDTable.GenericParam][i]).AddConstraints(this);
5515 SortTable(metaDataTables[(int)MDTable.GenericParamConstraint]);
5516 SortTable(metaDataTables[(int)MDTable.InterfaceImpl]);
5517 SortTable(metaDataTables[(int)MDTable.CustomAttribute]);
5521 internal void WriteByteCodes(FileImage output)
5523 for (int i=0; i < byteCodes.Count; i++) {
5524 ((CILInstructions)byteCodes[i]).Write(output);
5526 for (int i=0; i < byteCodePadding; i++) {
5527 output.Write((byte)0);
5531 internal void WriteResources (FileImage output)
5533 if (resources == null) return;
5534 for (int i = 0; i < resources.Count; i ++) {
5535 byte [] resBytes = (byte []) resources [i];
5536 output.Write ((uint) resBytes.Length);
5537 output.Write (resBytes);
5541 internal void WriteMetaData(FileImage output)
5543 this.output = output;
5544 mdStart = output.Seek(0,SeekOrigin.Current);
5545 // Console.WriteLine("Writing metaData at " + Hex.Long(mdStart));
5546 output.Write(MetaDataSignature);
5547 output.Write((short)1); // Major Version
5548 output.Write((short)1); // Minor Version ECMA = 0, PEFiles = 1
5549 output.Write(0); // Reserved
5550 output.Write(version.Length);
5551 output.Write(version.ToCharArray()); // version string is already zero padded
5552 output.Write((short)0);
5553 output.Write((ushort)numStreams);
5554 // write tilde header
5555 output.Write(tildeStart);
5556 output.Write(tildeTide + tildePadding);
5557 output.Write(tildeName);
5558 for (int i=1; i < numStreams; i++) streams[i].WriteHeader(output);
5559 // Console.WriteLine("Writing tilde stream at " + output.Seek(0,SeekOrigin.Current) + " = " + tildeStart);
5560 WriteTildeStream(output);
5561 for (int i=1; i < numStreams; i++) streams[i].Write(output);
5562 // Console.WriteLine("Finished Writing metaData at " + output.Seek(0,SeekOrigin.Current));
5565 internal bool LargeStringsIndex() { return strings.LargeIx(); }
5566 internal bool LargeGUIDIndex() { return guid.LargeIx(); }
5567 internal bool LargeUSIndex() { return us.LargeIx(); }
5568 internal bool LargeBlobIndex() { return blob.LargeIx(); }
5570 internal bool LargeIx(MDTable tabIx) { return largeIx[(uint)tabIx]; }
5573 private uint NumToAlign(uint val, uint alignVal)
5575 if ((val % alignVal) == 0) return 0;
5576 return alignVal - (val % alignVal);
5579 internal void WriteCodedIndex(CIx code, MetaDataElement elem, FileImage output)
5583 ix = (elem.Row << CIxShiftMap[(uint)code]) | elem.GetCodedIx(code);
5584 // Console.WriteLine("coded index = " + ix + " row = " + elem.Row);
5586 // Console.WriteLine("elem for coded index is null");
5588 if (lgeCIx[(uint)code])
5591 output.Write((ushort)ix);
5596 /**************************************************************************/
5598 /// Stream in the Meta Data (#Strings, #US, #Blob and #GUID)
5601 internal class MetaDataStream : BinaryWriter {
5603 private static readonly uint StreamHeaderSize = 8;
5604 private static uint maxSmlIxSize = 0xFFFF;
5606 private uint start = 0;
5607 uint size = 0, tide = 1;
5608 bool largeIx = false;
5611 Hashtable htable = new Hashtable();
5612 Hashtable btable = new Hashtable (new ByteArrayHashCodeProvider (), new ByteArrayComparer ());
5614 internal MetaDataStream(char[] name, bool addInitByte) : base(new MemoryStream())
5616 if (addInitByte) { Write((byte)0); size = 1; }
5618 sizeOfHeader = StreamHeaderSize + (uint)name.Length;
5621 internal MetaDataStream(char[] name, System.Text.Encoding enc, bool addInitByte) : base(new MemoryStream(),enc)
5623 if (addInitByte) { Write((byte)0); size = 1; }
5625 sizeOfHeader = StreamHeaderSize + (uint)name.Length;
5629 get { return start; }
5630 set { start = value; }
5633 internal uint headerSize()
5635 // Console.WriteLine(name + " stream has headersize of " + sizeOfHeader);
5636 return sizeOfHeader;
5639 internal void SetSize(uint siz)
5644 internal uint Size()
5649 internal bool LargeIx()
5654 internal void WriteDetails()
5656 // Console.WriteLine(name + " - size = " + size);
5659 internal uint Add(string str, bool prependSize)
5661 Object val = htable[str];
5665 htable[str] = index;
5666 char[] arr = str.ToCharArray();
5667 if (prependSize) CompressNum((uint)arr.Length*2+1);
5670 size = (uint)Seek(0,SeekOrigin.Current);
5676 internal uint Add (byte[] str, bool prependSize)
5678 Object val = btable [str];
5682 btable [str] = index;
5683 if (prependSize) CompressNum ((uint) str.Length);
5685 size = (uint) Seek (0, SeekOrigin.Current);
5693 internal uint Add(Guid guid, bool prependSize)
5695 byte [] b = guid.ToByteArray ();
5696 if (prependSize) CompressNum ((uint) b.Length);
5697 Write(guid.ToByteArray());
5698 size =(uint)Seek(0,SeekOrigin.Current);
5702 internal uint Add(byte[] blob)
5705 CompressNum((uint)blob.Length);
5707 size = (uint)Seek(0,SeekOrigin.Current);
5711 internal uint Add(byte val, bool prependSize)
5714 if (prependSize) CompressNum (1);
5716 size = (uint)Seek(0,SeekOrigin.Current);
5720 internal uint Add(sbyte val, bool prependSize)
5723 if (prependSize) CompressNum (1);
5725 size = (uint)Seek(0,SeekOrigin.Current);
5729 internal uint Add(ushort val, bool prependSize)
5732 if (prependSize) CompressNum (2);
5734 size = (uint)Seek(0,SeekOrigin.Current);
5738 internal uint Add(short val, bool prependSize)
5741 if (prependSize) CompressNum (2);
5743 size = (uint)Seek(0,SeekOrigin.Current);
5747 internal uint Add(uint val, bool prependSize)
5750 if (prependSize) CompressNum (4);
5752 size = (uint)Seek(0,SeekOrigin.Current);
5756 internal uint Add(int val, bool prependSize)
5759 if (prependSize) CompressNum (4);
5761 size = (uint)Seek(0,SeekOrigin.Current);
5765 internal uint Add(ulong val, bool prependSize)
5768 if (prependSize) CompressNum (8);
5770 size = (uint)Seek(0,SeekOrigin.Current);
5774 internal uint Add(long val, bool prependSize)
5777 if (prependSize) CompressNum (8);
5779 size = (uint)Seek(0,SeekOrigin.Current);
5783 internal uint Add(float val, bool prependSize)
5786 if (prependSize) CompressNum (4);
5788 size = (uint)Seek(0,SeekOrigin.Current);
5792 internal uint Add(double val, bool prependSize)
5795 if (prependSize) CompressNum (8);
5797 size = (uint)Seek(0,SeekOrigin.Current);
5801 private void CompressNum(uint val)
5805 } else if (val < 0x3FFF) {
5806 byte b1 = (byte)((val >> 8) | 0x80);
5807 byte b2 = (byte)(val & FileImage.iByteMask[0]);
5811 byte b1 = (byte)((val >> 24) | 0xC0);
5812 byte b2 = (byte)((val & FileImage.iByteMask[2]) >> 16);
5813 byte b3 = (byte)((val & FileImage.iByteMask[1]) >> 8);;
5814 byte b4 = (byte)(val & FileImage.iByteMask[0]);
5822 private void QuadAlign()
5824 if ((size % 4) != 0) {
5825 uint pad = 4 - (size % 4);
5827 for (int i=0; i < pad; i++) {
5833 internal void EndStream()
5836 if (size > maxSmlIxSize) {
5841 internal void WriteHeader(BinaryWriter output)
5843 output.Write(start);
5848 internal virtual void Write(BinaryWriter output)
5850 // Console.WriteLine("Writing " + name + " stream at " + output.Seek(0,SeekOrigin.Current) + " = " + start);
5851 MemoryStream str = (MemoryStream)BaseStream;
5852 output.Write(str.ToArray());
5857 /**************************************************************************/
5858 class ByteArrayComparer : IComparer {
5860 public int Compare (object x, object y)
5862 byte [] a = (byte []) x;
5863 byte [] b = (byte []) y;
5866 if (b.Length != len)
5869 for (int i = 0; i < len; ++i)
5876 class ByteArrayHashCodeProvider : IHashCodeProvider {
5878 public int GetHashCode (Object key)
5880 byte [] arr = (byte []) key;
5881 int len = arr.Length;
5884 for (int i = 0; i < len; ++i)
5885 h = (h << 5) - h + arr [i];