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;
448 internal CustomAttribute(MetaDataElement paren, Method constrType,
452 tabIx = MDTable.CustomAttribute;
456 internal override uint SortKey()
458 return (parent.Row << MetaData.CIxShiftMap[(uint)CIx.HasCustomAttr])
459 | parent.GetCodedIx(CIx.HasCustomAttr);
462 public void AddFieldOrProp(string name, Constant val)
465 names = new ArrayList();
466 vals = new ArrayList();
472 internal sealed override void BuildTables(MetaData md)
474 md.AddToTable(MDTable.CustomAttribute, this);
475 if (byteVal == null) {
480 BinaryWriter bw = new BinaryWriter(new MemoryStream());
482 MemoryStream str = (MemoryStream)bw.BaseStream;
483 valIx = md.AddToBlobHeap(str.ToArray());
486 internal sealed override uint Size(MetaData md)
488 return md.CodedIndexSize(CIx.HasCustomAttr) + md.CodedIndexSize(CIx.CustomAttributeType) + md.BlobIndexSize();
491 internal sealed override void Write(FileImage output)
493 output.WriteCodedIndex(CIx.HasCustomAttr,parent);
494 output.WriteCodedIndex(CIx.CustomAttributeType,type);
495 output.BlobIndex(valIx);
500 /**************************************************************************/
502 /// Descriptor for security permissions for a class or a method
505 public abstract class BaseDeclSecurity : MetaDataElement {
508 MetaDataElement parent;
511 internal BaseDeclSecurity(MetaDataElement paren, ushort act)
515 tabIx = MDTable.DeclSecurity;
518 internal override uint SortKey()
520 return (parent.Row << MetaData.CIxShiftMap[(uint)CIx.HasDeclSecurity])
521 | parent.GetCodedIx(CIx.HasDeclSecurity);
524 internal sealed override uint Size(MetaData md)
526 return 2 + md.CodedIndexSize(CIx.HasDeclSecurity) + md.BlobIndexSize();
529 internal sealed override void BuildTables(MetaData md)
533 BinaryWriter bw = new BinaryWriter (new MemoryStream ());
534 md.AddToTable (MDTable.DeclSecurity, this);
535 MemoryStream str = (MemoryStream)bw.BaseStream;
537 permissionIx = md.AddToBlobHeap(str.ToArray());
542 internal abstract void WriteSig (BinaryWriter bw);
544 internal sealed override void Write(FileImage output)
546 output.Write(action);
547 output.WriteCodedIndex(CIx.HasDeclSecurity,parent);
548 output.BlobIndex(permissionIx);
553 public class DeclSecurity : BaseDeclSecurity {
557 internal DeclSecurity(MetaDataElement paren, ushort act, byte [] val)
563 internal override void WriteSig (BinaryWriter bw)
570 public class DeclSecurity_20 : BaseDeclSecurity {
574 internal DeclSecurity_20 (MetaDataElement paren, ushort act, PermissionSet ps)
580 internal override void WriteSig (BinaryWriter bw)
586 public class PermissionMember {
588 MemberTypes member_type;
593 public PermissionMember (MemberTypes member_type, PEAPI.Type type, string name, object value)
595 this.member_type = member_type;
601 public void Write (BinaryWriter bw)
605 if (member_type == MemberTypes.Field)
606 bw.Write ((byte) 0x53);
609 bw.Write ((byte) 0x54);
611 if (type is PrimitiveType) {
612 bw.Write (type.GetTypeIndex ());
615 bw.Write ((byte) 0x55); //ENUM
617 b = Encoding.UTF8.GetBytes (((ClassRef) type).TypeName ());
618 MetaData.CompressNum ((uint) b.Length, (MemoryStream) bw.BaseStream);
622 b = Encoding.UTF8.GetBytes (name);
623 MetaData.CompressNum ((uint) b.Length, (MemoryStream) bw.BaseStream);
626 ((Constant) value).Write (bw);
631 public class Permission
639 public Permission (PEAPI.Type type, string name)
645 public void AddMember (PEAPI.PermissionMember member)
648 members = new ArrayList ();
650 members.Add (member);
653 public void Write (BinaryWriter bw)
655 byte [] b = Encoding.UTF8.GetBytes (name);
656 MetaData.CompressNum ((uint) b.Length, (MemoryStream) bw.BaseStream);
659 BinaryWriter perm_writer = new BinaryWriter (new MemoryStream (), Encoding.Unicode);
660 MemoryStream str = (MemoryStream) perm_writer.BaseStream;
662 MetaData.CompressNum ((uint) members.Count, str);//number of params
663 foreach (PermissionMember member in members)
664 member.Write (perm_writer);
666 bw.Write ((byte) str.Length); //(optional) parameters length
667 bw.Write (str.ToArray ());
671 public class PermissionSet
673 PEAPI.SecurityAction sec_action;
674 ArrayList permissions;
676 public PermissionSet (PEAPI.SecurityAction sec_action)
678 this.sec_action = sec_action;
681 public void AddPermission (PEAPI.Permission perm)
683 if (permissions == null)
684 permissions = new ArrayList ();
686 permissions.Add (perm);
689 public void Write (BinaryWriter bw)
691 bw.Write ((byte) 0x2e);
692 MetaData.CompressNum ((uint) permissions.Count, (MemoryStream) bw.BaseStream);
694 foreach (Permission perm in permissions)
700 /**************************************************************************/
702 /// Descriptor for layout information for a field
705 public class FieldLayout : MetaDataElement {
710 internal FieldLayout(Field field, uint offset)
713 this.offset = offset;
714 tabIx = MDTable.FieldLayout;
717 internal sealed override uint Size(MetaData md)
719 return 4 + md.TableIndexSize(MDTable.Field);
722 internal sealed override void Write(FileImage output)
724 output.Write(offset);
725 output.WriteIndex(MDTable.Field,field.Row);
730 /*****************************************************************************/
732 /// Marshalling information for a field or param
734 public class FieldMarshal : MetaDataElement {
736 MetaDataElement field;
740 internal FieldMarshal(MetaDataElement field, NativeType nType)
744 tabIx = MDTable.FieldMarshal;
747 internal override uint SortKey()
749 return (field.Row << MetaData.CIxShiftMap[(uint)CIx.HasFieldMarshal])
750 | field.GetCodedIx(CIx.HasFieldMarshal);
753 internal sealed override void BuildTables(MetaData md)
756 ntIx = md.AddToBlobHeap(nt.ToBlob());
760 internal sealed override uint Size(MetaData md)
762 return md.CodedIndexSize(CIx.HasFieldMarshal) + md.BlobIndexSize();
765 internal sealed override void Write(FileImage output)
767 output.WriteCodedIndex(CIx.HasFieldMarshal,field);
768 output.BlobIndex(ntIx);
773 /**************************************************************************/
775 /// Descriptor for the address of a field's value in the PE file
777 public class FieldRVA : MetaDataElement {
782 internal FieldRVA(Field field, DataConstant data)
786 tabIx = MDTable.FieldRVA;
789 internal sealed override void BuildTables(MetaData md)
796 internal sealed override uint Size(MetaData md)
798 return 4 + md.TableIndexSize(MDTable.Field);
801 internal sealed override void Write(FileImage output)
803 output.WriteDataRVA(data.DataOffset);
804 output.WriteIndex(MDTable.Field,field.Row);
809 /**************************************************************************/
811 /// Descriptor for a file referenced in THIS assembly/module (.file)
813 public class FileRef : MetaDataElement {
815 private static readonly uint NoMetaData = 0x1;
816 uint nameIx = 0, hashIx = 0;
818 protected string name;
820 internal FileRef(string name, byte[] hashBytes, bool metaData,
821 bool entryPoint, MetaData md) {
822 if (!metaData) flags = NoMetaData;
823 if (entryPoint) md.SetEntryPoint(this);
825 nameIx = md.AddToStringsHeap(name);
826 hashIx = md.AddToBlobHeap(hashBytes);
827 tabIx = MDTable.File;
830 internal FileRef(uint nameIx, byte[] hashBytes, bool metaData,
831 bool entryPoint, MetaData md) {
832 if (!metaData) flags = NoMetaData;
833 if (entryPoint) md.SetEntryPoint(this);
834 this.nameIx = nameIx;
835 hashIx = md.AddToBlobHeap(hashBytes);
836 tabIx = MDTable.File;
839 internal sealed override uint Size(MetaData md)
841 return 4 + md.StringsIndexSize() + md.BlobIndexSize();
844 internal sealed override void BuildTables(MetaData md)
846 md.AddToTable(MDTable.File,this);
849 internal sealed override void Write(FileImage output)
852 output.StringsIndex(nameIx);
853 output.BlobIndex(hashIx);
856 internal sealed override uint GetCodedIx(CIx code)
859 case (CIx.HasCustomAttr) : return 16;
860 case (CIx.Implementation) : return 0;
866 /**************************************************************************/
868 /// Descriptor for pinvoke information for a method NOT YET IMPLEMENTED
870 public class ImplMap : MetaDataElement {
872 private static readonly ushort NoMangle = 0x01;
877 ModuleRef importScope;
879 internal ImplMap(ushort flag, Method implMeth, string iName, ModuleRef mScope)
884 importScope = mScope;
885 tabIx = MDTable.ImplMap;
886 if (iName == null) flags |= NoMangle;
887 //throw(new NotYetImplementedException("PInvoke "));
890 internal override uint SortKey()
892 return (meth.Row << MetaData.CIxShiftMap[(uint)CIx.MemberForwarded])
893 | meth.GetCodedIx(CIx.MemberForwarded);
896 internal sealed override void BuildTables(MetaData md)
899 iNameIx = md.AddToStringsHeap(importName);
903 internal sealed override uint Size(MetaData md)
905 return 2+ md.CodedIndexSize(CIx.MemberForwarded) +
906 md.StringsIndexSize() + md.TableIndexSize(MDTable.ModuleRef);
909 internal sealed override void Write(FileImage output)
912 output.WriteCodedIndex(CIx.MemberForwarded,meth);
913 output.StringsIndex(iNameIx);
914 output.WriteIndex(MDTable.ModuleRef,importScope.Row);
919 /**************************************************************************/
921 public class GenericParameter : MetaDataElement {
923 MetaDataElement owner;
928 GenericParamAttributes attr;
930 internal GenericParameter (ClassDef owner, MetaData metadata,
931 short index, string name, GenericParamAttributes attr) : this (owner, metadata, index, name, attr, true)
935 internal GenericParameter (MethodDef owner, MetaData metadata,
936 short index, string name, GenericParamAttributes attr) : this (owner, metadata, index, name, attr, true)
940 private GenericParameter (MetaDataElement owner, MetaData metadata,
941 short index, string name, GenericParamAttributes attr, bool nadda) {
943 this.metadata = metadata;
945 tabIx = MDTable.GenericParam;
950 internal override uint SortKey()
952 return (owner.Row << MetaData.CIxShiftMap[(uint)CIx.TypeOrMethodDef])
953 | owner.GetCodedIx(CIx.TypeOrMethodDef);
956 internal override uint SortKey2 ()
961 public void AddConstraint (Type constraint)
963 metadata.AddToTable (MDTable.GenericParamConstraint,
964 new GenericParamConstraint (this, constraint));
967 internal sealed override uint Size(MetaData md)
970 md.CodedIndexSize(CIx.TypeOrMethodDef) +
971 md.StringsIndexSize ());
974 internal sealed override void BuildTables(MetaData md)
977 nameIx = md.AddToStringsHeap(name);
981 internal sealed override void Write(FileImage output)
983 output.Write ((short) index);
984 output.Write ((short) attr);
985 output.WriteCodedIndex(CIx.TypeOrMethodDef, owner);
986 output.StringsIndex (nameIx);
989 internal sealed override uint GetCodedIx(CIx code)
992 case (CIx.HasCustomAttr) : return 19;
999 internal class GenericParamConstraint : MetaDataElement {
1001 GenericParameter param;
1004 public GenericParamConstraint (GenericParameter param, Type type)
1008 tabIx = MDTable.GenericParamConstraint;
1011 internal override uint SortKey()
1016 internal sealed override uint Size(MetaData md)
1018 return (uint) (md.TableIndexSize(MDTable.GenericParam) +
1019 md.CodedIndexSize(CIx.TypeDefOrRef));
1022 internal sealed override void Write(FileImage output)
1024 output.WriteIndex(MDTable.GenericParam, param.Row);
1025 output.WriteCodedIndex(CIx.TypeDefOrRef, type);
1030 internal class MethodSpec : Method {
1033 GenericMethodSig g_sig;
1036 internal MethodSpec (Method meth, GenericMethodSig g_sig) : base ("")
1040 tabIx = MDTable.MethodSpec;
1043 internal override uint GetSigIx (MetaData md)
1045 throw new Exception ("Should not be used.");
1048 public override void AddCallConv (CallConv cconv)
1050 throw new Exception ("Should not be used.");
1053 internal sealed override void BuildTables (MetaData md)
1056 sidx = g_sig.GetSigIx (md);
1060 internal sealed override uint Size (MetaData md)
1062 return (uint) (md.CodedIndexSize(CIx.MethodDefOrRef) +
1063 md.BlobIndexSize ());
1066 internal sealed override void Write (FileImage output)
1068 output.WriteCodedIndex (CIx.MethodDefOrRef, meth);
1069 output.BlobIndex (sidx);
1072 internal sealed override void TypeSig (MemoryStream sig)
1074 throw new Exception ("Should not be used.");
1078 /**************************************************************************/
1080 /// Descriptor for interface implemented by a class
1082 public class InterfaceImpl: MetaDataElement {
1087 internal InterfaceImpl(ClassDef theClass, Class theInterface)
1089 this.theClass = theClass;
1090 this.theInterface = theInterface;
1091 tabIx = MDTable.InterfaceImpl;
1094 internal sealed override uint Size(MetaData md)
1096 return md.TableIndexSize(MDTable.TypeDef) +
1097 md.CodedIndexSize(CIx.TypeDefOrRef);
1100 internal sealed override void Write(FileImage output)
1102 output.WriteIndex(MDTable.TypeDef,theClass.Row);
1103 output.WriteCodedIndex(CIx.TypeDefOrRef,theInterface);
1106 internal sealed override uint GetCodedIx(CIx code) { return 5; }
1108 internal override uint SortKey ()
1110 return (theClass.Row << MetaData.CIxShiftMap[(uint)CIx.TypeDefOrRef])
1111 | theClass.GetCodedIx (CIx.TypeDefOrRef);
1116 /**************************************************************************/
1118 /// Descriptor for resources used in this PE file
1121 public class ManifestResource : MetaDataElement {
1123 public static readonly uint PublicResource = 0x1;
1124 public static readonly uint PrivateResource = 0x2;
1127 MetaDataElement rRef;
1131 byte [] resourceBytes;
1133 public ManifestResource (string name, byte[] resBytes, uint flags)
1135 InitResource (name, flags);
1136 this.resourceBytes = resBytes;
1139 public ManifestResource(string name, uint flags, FileRef fileRef)
1141 InitResource (name, flags);
1145 public ManifestResource(string name, uint flags, FileRef fileRef,
1147 InitResource (name, flags);
1149 fileOffset = fileIx;
1152 public ManifestResource(string name, uint flags, AssemblyRef assemRef)
1154 InitResource (name, flags);
1158 internal ManifestResource (ManifestResource mres)
1160 mrName = mres.mrName;
1163 fileOffset = mres.fileOffset;
1164 resourceBytes = mres.resourceBytes;
1167 private void InitResource (string name, uint flags)
1171 tabIx = MDTable.ManifestResource;
1174 internal sealed override void BuildTables(MetaData md)
1177 md.AddToTable (MDTable.ManifestResource, this);
1178 nameIx = md.AddToStringsHeap(mrName);
1179 if (resourceBytes != null) {
1181 throw new PEFileException ("Manifest Resource has byte value and file reference");
1182 fileOffset = md.AddResource(resourceBytes);
1185 throw new PEFileException ("Manifest Resource has no implementation or value");
1186 rRef.BuildTables (md);
1192 internal sealed override uint Size(MetaData md)
1194 return 8 + md.StringsIndexSize() +
1195 md.CodedIndexSize(CIx.Implementation);
1198 internal sealed override void Write(FileImage output)
1200 output.Write(fileOffset);
1201 output.Write(flags);
1202 output.StringsIndex(nameIx);
1203 output.WriteCodedIndex(CIx.Implementation,rRef);
1206 internal sealed override uint GetCodedIx(CIx code) { return 18; }
1208 public string Name {
1209 get { return mrName; }
1210 set { mrName = value; }
1214 /**************************************************************************/
1216 /// Base class for elements in the PropertyMap, EventMap and
1217 /// NestedClass MetaData tables
1219 public class MapElem : MetaDataElement {
1225 internal MapElem(ClassDef par, uint elIx, MDTable elemTab)
1229 elemTable = elemTab;
1232 internal sealed override uint Size(MetaData md)
1234 return md.TableIndexSize(MDTable.TypeDef) + md.TableIndexSize(elemTable);
1237 internal sealed override void Write(FileImage output)
1239 output.WriteIndex(MDTable.TypeDef,parent.Row);
1240 output.WriteIndex(elemTable,elemIx);
1244 /**************************************************************************/
1246 /// Descriptor for an overriding method (.override)
1248 public class MethodImpl : MetaDataElement {
1251 Method header, body;
1253 internal MethodImpl(ClassDef par, Method decl, Method bod)
1258 tabIx = MDTable.MethodImpl;
1261 internal sealed override uint Size(MetaData md)
1263 return md.TableIndexSize(MDTable.TypeDef) + 2 * md.CodedIndexSize(CIx.MethodDefOrRef);
1266 internal sealed override void Write(FileImage output)
1268 output.WriteIndex(MDTable.TypeDef,parent.Row);
1269 output.WriteCodedIndex(CIx.MethodDefOrRef,body);
1270 output.WriteCodedIndex(CIx.MethodDefOrRef,header);
1275 /**************************************************************************/
1277 /// Descriptor for Property and Event methods
1279 public class MethodSemantics : MetaDataElement {
1281 Feature.MethodType type;
1283 Feature eventOrProp;
1285 internal MethodSemantics(Feature.MethodType mType, MethodDef method, Feature feature)
1289 eventOrProp = feature;
1290 tabIx = MDTable.MethodSemantics;
1293 internal override uint SortKey()
1295 return (eventOrProp.Row << MetaData.CIxShiftMap [(uint)CIx.HasSemantics])
1296 | eventOrProp.GetCodedIx (CIx.HasSemantics);
1299 internal sealed override uint Size(MetaData md)
1301 return 2 + md.TableIndexSize(MDTable.Method) + md.CodedIndexSize(CIx.HasSemantics);
1304 internal sealed override void Write(FileImage output)
1306 output.Write((ushort)type);
1307 output.WriteIndex(MDTable.Method,meth.Row);
1308 output.WriteCodedIndex(CIx.HasSemantics,eventOrProp);
1313 /**************************************************************************/
1315 /// Descriptor for a parameter of a method defined in this assembly/module
1317 public class Param : MetaDataElement {
1322 internal ushort seqNo = 0;
1324 ConstantElem defaultVal;
1326 FieldMarshal marshalInfo;
1329 /// Create a new parameter for a method
1331 /// <param name="mode">param mode (in, out, opt)</param>
1332 /// <param name="parName">parameter name</param>
1333 /// <param name="parType">parameter type</param>
1334 public Param(ParamAttr mode, string parName, Type parType)
1338 parMode = (ushort)mode;
1339 tabIx = MDTable.Param;
1342 public bool HasMarshalInfo {
1343 get { return marshalInfo != null; }
1347 /// Add a default value to this parameter
1349 /// <param name="c">the default value for the parameter</param>
1350 public void AddDefaultValue(Constant cVal)
1352 defaultVal = new ConstantElem(this,cVal);
1353 parMode |= (ushort) ParamAttr.HasDefault;
1357 /// Add marshalling information about this parameter
1359 public void AddMarshallInfo(NativeType marshallType)
1361 parMode |= (ushort) ParamAttr.HasFieldMarshal;
1362 marshalInfo = new FieldMarshal(this,marshallType);
1365 internal Type GetParType() { return pType; }
1367 internal sealed override void BuildTables(MetaData md)
1370 nameIx = md.AddToStringsHeap(pName);
1371 if (defaultVal != null) {
1372 md.AddToTable(MDTable.Constant,defaultVal);
1373 defaultVal.BuildTables(md);
1375 if (marshalInfo != null) {
1376 md.AddToTable(MDTable.FieldMarshal,marshalInfo);
1377 marshalInfo.BuildTables(md);
1382 internal void TypeSig(MemoryStream str)
1387 internal sealed override uint Size(MetaData md)
1389 return 4 + md.StringsIndexSize();
1392 internal sealed override void Write(FileImage output)
1394 output.Write(parMode);
1395 output.Write(seqNo);
1396 output.StringsIndex(nameIx);
1399 internal sealed override uint GetCodedIx(CIx code)
1402 case (CIx.HasCustomAttr) : return 4;
1403 case (CIx.HasConst) : return 1;
1404 case (CIx.HasFieldMarshal) : return 1;
1411 /**************************************************************************/
1412 public abstract class Signature : MetaDataElement {
1414 protected uint sigIx;
1416 internal Signature()
1418 tabIx = MDTable.StandAloneSig;
1421 internal sealed override uint Size(MetaData md)
1423 return md.BlobIndexSize();
1426 internal sealed override void Write(FileImage output)
1428 output.BlobIndex(sigIx);
1431 internal sealed override uint GetCodedIx(CIx code) { return (uint)tabIx; }
1435 /**************************************************************************/
1436 public class TypeSpec : MetaDataElement {
1439 internal TypeSpec(Type aType, MetaData md)
1441 MemoryStream sig = new MemoryStream();
1443 sigIx = md.AddToBlobHeap(sig.ToArray());
1444 tabIx = MDTable.TypeSpec;
1447 internal sealed override uint GetCodedIx(CIx code)
1450 case (CIx.TypeDefOrRef) : return 2;
1451 case (CIx.HasCustomAttr) : return 13;
1452 case (CIx.MemberRefParent) : return 4;
1457 internal override uint Size(MetaData md)
1459 return md.BlobIndexSize();
1462 internal sealed override void Write(FileImage output)
1464 //Console.WriteLine("Writing the blob index for a TypeSpec");
1465 output.BlobIndex(sigIx);
1470 /**************************************************************************/
1472 /// Base class for all IL types
1474 public abstract class Type : MetaDataElement {
1475 protected byte typeIndex;
1476 protected TypeSpec typeSpec;
1478 internal Type(byte tyIx) { typeIndex = tyIx; }
1480 internal byte GetTypeIndex() { return typeIndex; }
1481 internal void SetTypeIndex (byte b) { typeIndex = b; }
1483 internal virtual MetaDataElement GetTypeSpec(MetaData md)
1485 if (typeSpec == null) {
1486 typeSpec = new TypeSpec(this,md);
1487 md.AddToTable(MDTable.TypeSpec,typeSpec);
1492 internal virtual void TypeSig(MemoryStream str)
1494 throw(new TypeSignatureException(this.GetType().AssemblyQualifiedName +
1495 " doesn't have a type signature!!"));
1499 public class ClassRefInst : Type {
1502 private bool is_value;
1504 public ClassRefInst (Type type, bool is_value) : base (PrimitiveType.Class.GetTypeIndex ())
1507 this.is_value = is_value;
1509 typeIndex = PrimitiveType.ValueType.GetTypeIndex ();
1510 tabIx = MDTable.TypeSpec;
1513 internal sealed override void TypeSig(MemoryStream str)
1519 /**************************************************************************/
1521 /// The base descriptor for a class
1523 public abstract class Class : Type {
1525 protected int row = 0;
1526 public string name, nameSpace;
1527 protected uint nameIx, nameSpaceIx;
1528 protected MetaData _metaData;
1529 internal Class(string nameSpaceName, string className, MetaData md)
1530 : base(PrimitiveType.Class.GetTypeIndex ())
1532 nameSpace = nameSpaceName;
1534 nameIx = md.AddToStringsHeap(name);
1535 nameSpaceIx = md.AddToStringsHeap(nameSpace);
1539 internal Class(uint nsIx, uint nIx) : base(PrimitiveType.Class.GetTypeIndex ())
1545 internal Class (byte typeIndex) : base (typeIndex)
1547 nameSpace = "Should not be used";
1548 name = "Should not be used";
1551 internal virtual uint TypeDefOrRefToken() { return 0; }
1553 internal virtual void MakeValueClass(ValueClass vClass)
1555 typeIndex = PrimitiveType.ValueType.GetTypeIndex ();
1558 internal virtual string TypeName()
1560 return (nameSpace + "." + name);
1563 internal override MetaDataElement GetTypeSpec(MetaData md)
1569 /**************************************************************************/
1570 // This Class produces entries in the TypeDef table of the MetaData
1571 // in the PE meta data.
1573 // NOTE: Entry 0 in TypeDef table is always the pseudo class <module>
1574 // which is the parent for functions and variables declared a module level
1577 /// The descriptor for a class defined in the IL (.class) in the current assembly/module
1580 public class ClassDef : Class {
1583 ArrayList fields = new ArrayList();
1584 ArrayList methods = new ArrayList();
1586 ArrayList properties;
1587 bool typeIndexChecked = true;
1588 uint fieldIx = 0, methodIx = 0;
1591 ClassDef parentClass;
1594 internal ClassDef(TypeAttr attrSet, string nsName, string name,
1595 MetaData md) : base(nsName, name, md)
1598 if (! ((nsName == "" && name == "<Module>") || (nsName == "System" && name == "Object")) ) {
1599 superType = metaData.mscorlib.GetSpecialSystemClass(PrimitiveType.Object);
1601 flags = (uint)attrSet;
1602 tabIx = MDTable.TypeDef;
1605 internal void SetSuper(Class sClass)
1608 if (! (sClass is GenericTypeInst))
1609 typeIndexChecked = false;
1612 internal override void MakeValueClass(ValueClass vClass)
1614 if (vClass == ValueClass.Enum)
1615 superType = metaData.mscorlib.EnumType();
1617 superType = metaData.mscorlib.ValueType();
1619 typeIndex = PrimitiveType.ValueType.GetTypeIndex ();
1622 public void SpecialNoSuper()
1628 /// Add an attribute to this class
1630 /// <param name="ta">the attribute to be added</param>
1631 public void AddAttribute(TypeAttr ta)
1637 /// Add an interface that is implemented by this class
1639 /// <param name="iFace">the interface that is implemented</param>
1640 public void AddImplementedInterface(Class iFace)
1642 metaData.AddToTable(MDTable.InterfaceImpl,new InterfaceImpl(this,iFace));
1646 /// Add a named generic type parameter
1648 public GenericParameter AddGenericParameter (short index, string name)
1650 return AddGenericParameter (index, name, 0);
1654 /// Add a named generic type parameter with attributes
1656 public GenericParameter AddGenericParameter (short index, string name, GenericParamAttributes attr)
1658 GenericParameter gp = new GenericParameter (this, metaData, index, name, attr);
1659 metaData.AddToTable (MDTable.GenericParam, gp);
1664 /// Add a field to this class
1666 /// <param name="name">field name</param>
1667 /// <param name="fType">field type</param>
1668 /// <returns>a descriptor for this new field</returns>
1669 public FieldDef AddField(string name, Type fType)
1671 FieldDef field = new FieldDef(name,fType);
1677 /// Add a field to this class
1679 /// <param name="fAtts">attributes for this field</param>
1680 /// <param name="name">field name</param>
1681 /// <param name="fType">field type</param>
1682 /// <returns>a descriptor for this new field</returns>
1683 public FieldDef AddField(FieldAttr fAtts, string name, Type fType)
1685 FieldDef field = new FieldDef(fAtts,name,fType);
1690 public void SetFieldOrder (ArrayList fields)
1692 this.fields = fields;
1696 /// Add a method to this class
1698 /// <param name="name">method name</param>
1699 /// <param name="retType">return type</param>
1700 /// <param name="pars">parameters</param>
1701 /// <returns>a descriptor for this new method</returns>
1702 public MethodDef AddMethod(string name, Type retType, Param[] pars)
1704 return AddMethod (name, new Param (ParamAttr.Default, "", retType), pars);
1707 public MethodDef AddMethod (string name, Param ret_param, Param [] pars)
1709 // Console.WriteLine("Adding method " + name + " to class " + this.name);
1710 MethodDef meth = new MethodDef(metaData,name, ret_param, pars);
1716 /// Add a method to this class
1718 /// <param name="mAtts">attributes for this method</param>
1719 /// <param name="iAtts">implementation attributes for this method</param>
1720 /// <param name="name">method name</param>
1721 /// <param name="retType">return type</param>
1722 /// <param name="pars">parameters</param>
1723 /// <returns>a descriptor for this new method</returns>
1724 public MethodDef AddMethod(MethAttr mAtts, ImplAttr iAtts, string name,
1725 Param ret_param, Param [] pars) {
1726 // Console.WriteLine("Adding method " + name + " to class " + this.name);
1727 MethodDef meth = new MethodDef (metaData, mAtts, iAtts, name, ret_param, pars);
1733 /// Add an event to this class
1735 /// <param name="name">event name</param>
1736 /// <param name="eType">event type</param>
1737 /// <returns>a descriptor for this new event</returns>
1738 public Event AddEvent(string name, Type eType)
1740 Event e = new Event(name,eType,this);
1741 if (events == null) events = new ArrayList();
1747 /// Add a property to this class
1749 /// <param name="name">property name</param>
1750 /// <param name="propType">property type</param>
1751 /// <returns>a descriptor for this new property</returns>
1752 public Property AddProperty(string name, Type retType, Type[] pars)
1754 Property p = new Property(name, retType, pars, this);
1755 if (properties == null) properties = new ArrayList();
1761 /// Add a nested class to this class
1763 /// <param name="attrSet">attributes for this nested class</param>
1764 /// <param name="nsName">nested name space name</param>
1765 /// <param name="name">nested class name</param>
1766 /// <returns>a descriptor for this new nested class</returns>
1767 public ClassDef AddNestedClass(TypeAttr attrSet, string nsName,
1769 ClassDef nClass = new ClassDef(attrSet,"",name,metaData);
1770 metaData.AddToTable(MDTable.TypeDef,nClass);
1771 metaData.AddToTable(MDTable.NestedClass,new MapElem(nClass,Row,MDTable.TypeDef));
1772 nClass.parentClass = this;
1776 public static bool IsValueType (Class type)
1778 return IsValueType (type.nameSpace, type.name);
1781 public static bool IsEnum (Class type)
1783 return IsEnum (type.nameSpace, type.name);
1786 public static bool IsValueType (string nsName, string name)
1788 return (nsName == "System" && name == "ValueType");
1791 public static bool IsEnum (string nsName, string name)
1793 return (nsName == "System" && name == "Enum");
1797 /// Add a nested class to this class
1799 /// <param name="attrSet">attributes for this nested class</param>
1800 /// <param name="nsName">nested name space name</param>
1801 /// <param name="name">nested class name</param>
1802 /// <param name="sType">super type of this nested class</param>
1803 /// <returns>a descriptor for this new nested class</returns>
1804 public ClassDef AddNestedClass(TypeAttr attrSet, string nsName,
1805 string name, Class sType) {
1806 ClassDef nClass = AddNestedClass (attrSet, nsName, name);
1807 nClass.SetSuper(sType);
1808 if (ClassDef.IsValueType (sType))
1809 nClass.MakeValueClass (ValueClass.ValueType);
1811 if (ClassDef.IsEnum (sType))
1812 nClass.MakeValueClass (ValueClass.Enum);
1814 if (ClassDef.IsValueType (sType) || ClassDef.IsEnum (sType))
1815 nClass.SetTypeIndex (PrimitiveType.ValueType.GetTypeIndex ());
1817 nClass.typeIndexChecked = true;
1822 /// Add layout information for this class. This class must have the
1823 /// sequential or explicit attribute.
1825 /// <param name="packSize">packing size (.pack)</param>
1826 /// <param name="classSize">class size (.size)</param>
1827 public void AddLayoutInfo (int packSize, int classSize)
1829 layout = new ClassLayout(packSize,classSize,this);
1833 /// Use a method as the implementation for another method (.override)
1835 /// <param name="decl">the method to be overridden</param>
1836 /// <param name="body">the implementation to be used</param>
1837 public void AddMethodOverride(Method decl, Method body)
1839 metaData.AddToTable(MDTable.MethodImpl,new MethodImpl(this,decl,body));
1843 /// Add security to this class NOT YET IMPLEMENTED
1845 /// <param name="permissionSet"></param>
1846 public void AddSecurity(byte[] permissionSet)
1848 throw(new NotYetImplementedException("Class security "));
1849 //flags |= HasSecurity;
1850 // securityActions = permissionSet;
1853 //public void AddLineInfo(int row, int col) { }
1855 internal void CheckTypeIndex()
1857 if (typeIndexChecked) return;
1858 if (superType is ClassDef)
1859 ((ClassDef)superType).CheckTypeIndex();
1860 typeIndex = superType.GetTypeIndex();
1861 typeIndexChecked = true;
1864 internal sealed override void BuildTables(MetaData md)
1867 if ((flags & (uint)TypeAttr.Interface) != 0) { superType = null; }
1868 // Console.WriteLine("Building tables for " + name);
1869 if (layout != null) md.AddToTable(MDTable.ClassLayout,layout);
1870 // Console.WriteLine("adding methods " + methods.Count);
1871 methodIx = md.TableIndex(MDTable.Method);
1872 for (int i=0; i < methods.Count; i++) {
1873 md.AddToTable(MDTable.Method,(MetaDataElement)methods[i]);
1874 ((MethodDef)methods[i]).BuildTables(md);
1876 // Console.WriteLine("adding fields");
1877 fieldIx = md.TableIndex(MDTable.Field);
1878 for (int i=0; i < fields.Count; i++) {
1879 md.AddToTable(MDTable.Field,(MetaDataElement)fields[i]);
1880 ((FieldDef)fields[i]).BuildTables(md);
1882 // Console.WriteLine("adding events and properties");
1883 if (events != null) {
1884 for (int i=0; i < events.Count; i++) {
1885 md.AddToTable(MDTable.Event,(Event)events[i]);
1886 ((Event)events[i]).BuildTables(md);
1888 md.AddToTable(MDTable.EventMap,
1889 new MapElem(this,((Event)events[0]).Row,MDTable.Event));
1891 if (properties != null) {
1892 for (int i=0; i < properties.Count; i++) {
1893 md.AddToTable(MDTable.Property,(Property)properties[i]);
1894 ((Property)properties[i]).BuildTables(md);
1896 md.AddToTable(MDTable.PropertyMap,new MapElem(this,
1897 ((Property)properties[0]).Row,MDTable.Property));
1899 // Console.WriteLine("End of building tables");
1903 internal sealed override uint Size(MetaData md)
1905 return 4 + 2 * md.StringsIndexSize() +
1906 md.CodedIndexSize(CIx.TypeDefOrRef) +
1907 md.TableIndexSize(MDTable.Field) +
1908 md.TableIndexSize(MDTable.Method);
1911 internal sealed override void Write(FileImage output)
1913 output.Write(flags);
1914 output.StringsIndex(nameIx);
1915 output.StringsIndex(nameSpaceIx);
1916 //if (superType != null)
1917 // Console.WriteLine("getting coded index for superType of " + name + " = " + superType.GetCodedIx(CIx.TypeDefOrRef));
1918 output.WriteCodedIndex(CIx.TypeDefOrRef,superType);
1919 output.WriteIndex(MDTable.Field,fieldIx);
1920 output.WriteIndex(MDTable.Method,methodIx);
1923 internal sealed override uint TypeDefOrRefToken()
1930 internal sealed override void TypeSig(MemoryStream sig)
1932 if (!typeIndexChecked) CheckTypeIndex();
1933 sig.WriteByte(GetTypeIndex());
1934 MetaData.CompressNum(TypeDefOrRefToken(),sig);
1937 internal sealed override uint GetCodedIx(CIx code)
1940 case (CIx.TypeDefOrRef) : return 0;
1941 case (CIx.HasCustomAttr) : return 3;
1942 case (CIx.HasDeclSecurity) : return 0;
1943 case (CIx.TypeOrMethodDef) : return 0;
1950 /**************************************************************************/
1952 /// Descriptor for a class/interface declared in another module of THIS
1953 /// assembly, or in another assembly.
1955 public class ClassRef : Class, IExternRef, IResolutionScope {
1957 protected IResolutionScope parent;
1958 protected MetaData metaData;
1960 internal ClassRef(string nsName, string name, MetaData md) : base(nsName, name, md)
1963 tabIx = MDTable.TypeRef;
1967 /// Add a method to this class
1969 /// <param name="name">method name</param>
1970 /// <param name="retType">return type</param>
1971 /// <param name="pars">parameter types</param>
1972 /// <returns>a descriptor for this method</returns>
1973 public MethodRef AddMethod(string name, Type retType, Type[] pars)
1975 return AddMethod (name, retType, pars, 0);
1979 /// Add a method to this class
1981 /// <param name="name">method name</param>
1982 /// <param name="retType">return type</param>
1983 /// <param name="pars">parameter types</param>
1984 /// <param name="gen_param_count">num of generic parameters</param>
1985 /// <returns>a descriptor for this method</returns>
1986 public MethodRef AddMethod (string name, Type retType, Type[] pars, int gen_param_count)
1988 MethodRef meth = new MethodRef (this, name, retType, pars, false, null, gen_param_count);
1989 metaData.AddToTable(MDTable.MemberRef,meth);
1994 /// Add a method to this class
1996 /// <param name="name">method name</param>
1997 /// <param name="retType">return type</param>
1998 /// <param name="pars">parameter types</param>
1999 /// <returns>a descriptor for this method</returns>
2000 public MethodRef AddVarArgMethod(string name, Type retType,
2001 Type[] pars, Type[] optPars)
2003 MethodRef meth = new MethodRef(this,name,retType,pars,true,optPars, 0);
2004 metaData.AddToTable(MDTable.MemberRef,meth);
2009 /// Add a field to this class
2011 /// <param name="name">field name</param>
2012 /// <param name="fType">field type</param>
2013 /// <returns>a descriptor for this field</returns>
2014 public FieldRef AddField(string name, Type fType)
2016 FieldRef field = new FieldRef(this,name,fType);
2017 metaData.AddToTable(MDTable.MemberRef,field);
2021 public ClassRef AddClass (string nsName, string name)
2023 ClassRef aClass = new ClassRef(nsName,name,metaData);
2024 metaData.AddToTable(MDTable.TypeRef,aClass);
2025 aClass.SetParent(this);
2029 public ClassRef AddValueClass (string nsName, string name)
2031 ClassRef aClass = AddClass (nsName, name);
2032 aClass.MakeValueClass (ValueClass.ValueType);
2036 internal void SetParent(IResolutionScope par)
2041 internal override string TypeName()
2043 if ((parent != null) && (parent is AssemblyRef))
2044 return (nameSpace + "." + name + ", " + ((AssemblyRef)parent).TypeName());
2046 return (nameSpace + name);
2049 internal sealed override uint Size(MetaData md)
2051 return md.CodedIndexSize(CIx.ResolutionScope) + 2 *
2052 md.StringsIndexSize();
2055 internal sealed override void Write(FileImage output)
2057 output.WriteCodedIndex(CIx.ResolutionScope,(MetaDataElement) parent);
2058 output.StringsIndex(nameIx);
2059 output.StringsIndex(nameSpaceIx);
2062 internal override sealed uint TypeDefOrRefToken()
2065 cIx = (cIx << 2) | 0x1;
2069 internal override void TypeSig(MemoryStream sig)
2071 sig.WriteByte(GetTypeIndex());
2072 MetaData.CompressNum(TypeDefOrRefToken(),sig);
2075 internal sealed override uint GetCodedIx(CIx code)
2078 case (CIx.TypeDefOrRef) : return 1;
2079 case (CIx.HasCustomAttr) : return 2;
2080 case (CIx.MemberRefParent) : return 1;
2081 case (CIx.ResolutionScope) : return 3;
2088 /**************************************************************************/
2089 public class ExternClassRef : ClassRef {
2091 ExternClass externClass;
2093 internal ExternClassRef(TypeAttr attrs, string nsName, string name,
2094 MetaDataElement declRef, MetaData md) : base(nsName,name,md)
2096 externClass = new ExternClass(attrs,nameSpaceIx,nameIx,declRef);
2097 metaData.AddToTable(MDTable.ExportedType,externClass);
2100 internal ExternClassRef(string name, MetaData md) : base(null,name,md)
2104 public ClassRef AddNestedClass(TypeAttr attrs, string name)
2106 ExternClassRef nestedClass = new ExternClassRef(name,metaData);
2107 externClass = new ExternClass(attrs,0,nameIx,this.externClass);
2108 metaData.AddToTable(MDTable.ExportedType,externClass);
2114 /**************************************************************************/
2116 /// Descriptor for a class defined in another module of THIS assembly
2117 /// and exported (.class extern)
2120 internal class ExternClass : Class {
2122 MetaDataElement parent;
2125 internal ExternClass(TypeAttr attr, uint nsIx, uint nIx,
2126 MetaDataElement paren) : base(nsIx,nIx)
2130 tabIx = MDTable.ExportedType;
2133 internal sealed override uint Size(MetaData md)
2135 return 8 + 2* md.StringsIndexSize() + md.CodedIndexSize(CIx.Implementation);
2138 internal sealed override void Write(FileImage output)
2140 output.Write(flags);
2142 output.StringsIndex(nameIx);
2143 output.StringsIndex(nameSpaceIx);
2144 output.WriteCodedIndex(CIx.Implementation,parent);
2147 internal sealed override uint GetCodedIx(CIx code)
2150 case (CIx.HasCustomAttr) : return 17;
2151 case (CIx.Implementation) : return 2;
2158 public class GenParam : Class {
2161 private string param_name;
2162 private uint sigIx = 0;
2164 public GenParam (int index, string name, GenParamType ptype) : base ((byte) ptype)
2167 this.param_name = name;
2168 tabIx = MDTable.TypeSpec;
2172 get { return index; }
2173 set { index = value; }
2176 public string Name {
2177 get { return param_name; }
2178 set { param_name = value; }
2181 public GenParamType Type {
2182 get { return (GenParamType) GetTypeIndex (); }
2185 internal sealed override void BuildTables (MetaData md)
2189 MemoryStream str = new MemoryStream ();
2191 sigIx = md.AddToBlobHeap (str.ToArray ());
2196 internal sealed override void TypeSig(MemoryStream str)
2199 throw new PEFileException (String.Format ("Unresolved {0} - {1}", (GenParamType) GetTypeIndex (), param_name));
2200 str.WriteByte(typeIndex);
2201 MetaData.CompressNum ((uint) index, str);
2204 internal override uint Size(MetaData md)
2206 return md.BlobIndexSize();
2209 internal sealed override void Write (FileImage output)
2211 output.BlobIndex (sigIx);
2214 internal sealed override uint GetCodedIx(CIx code)
2217 case (CIx.TypeDefOrRef) : return 2;
2218 case (CIx.HasCustomAttr) : return 13;
2219 case (CIx.MemberRefParent) : return 4;
2225 public class GenericTypeInst : Class {
2227 private Type gen_type;
2228 private Type[] gen_param;
2229 bool inTable = false;
2232 public GenericTypeInst (Type gen_type, Type[] gen_param)
2233 : base ((byte) PrimitiveType.GenericInst.GetTypeIndex ())
2235 this.gen_type = gen_type;
2236 this.gen_param = gen_param;
2237 tabIx = MDTable.TypeSpec;
2240 internal override MetaDataElement GetTypeSpec (MetaData md)
2243 md.AddToTable (MDTable.TypeSpec, this);
2250 internal sealed override void TypeSig(MemoryStream str)
2252 str.WriteByte(typeIndex);
2253 gen_type.TypeSig (str);
2254 MetaData.CompressNum ((uint) gen_param.Length, str);
2255 foreach (Type param in gen_param)
2256 param.TypeSig (str);
2259 internal sealed override void BuildTables (MetaData md)
2263 MemoryStream str = new MemoryStream ();
2265 sigIx = md.AddToBlobHeap (str.ToArray ());
2270 internal sealed override uint Size (MetaData md)
2272 return md.BlobIndexSize ();
2275 internal sealed override void Write (FileImage output)
2277 output.BlobIndex (sigIx);
2280 internal sealed override uint GetCodedIx (CIx code)
2283 case (CIx.TypeDefOrRef): return 2;
2284 case (CIx.MemberRefParent): return 4;
2285 case (CIx.HasCustomAttr): return 13;
2291 public class GenericMethodSig {
2293 private Type[] gen_param;
2295 private uint sigIx = 0;
2297 public GenericMethodSig (Type[] gen_param)
2299 this.gen_param = gen_param;
2303 internal void TypeSig (MemoryStream str)
2305 str.WriteByte (0x0A); /* GENERIC_INST */
2306 MetaData.CompressNum ((uint) gen_param.Length, str);
2307 foreach (Type param in gen_param)
2308 param.TypeSig (str);
2311 internal uint GetSigIx (MetaData md)
2316 MemoryStream sig = new MemoryStream();
2318 sigIx = md.AddToBlobHeap (sig.ToArray());
2324 public class Sentinel : Type {
2326 public Sentinel () : base (0x41) { }
2328 internal sealed override void TypeSig(MemoryStream str)
2330 str.WriteByte(typeIndex);
2334 /**************************************************************************/
2336 /// Descriptor for a FunctionPointer type
2339 public class MethPtrType : Type {
2351 /// Create a new function pointer type
2353 /// <param name="meth">the function to be referenced</param>
2354 public MethPtrType (CallConv callconv, Type retType, Type[] pars,
2355 bool varArgMeth, Type[] optPars) : base(0x1B)
2357 this.retType = retType;
2358 callConv = callconv;
2360 this.varArgMeth = varArgMeth;
2361 if (parList != null) numPars = (uint)parList.Length;
2363 optParList = optPars;
2364 if (optParList != null) numOptPars = (uint)optParList.Length;
2365 callConv |= CallConv.Vararg;
2367 tabIx = MDTable.TypeSpec;
2370 internal sealed override void TypeSig(MemoryStream sig)
2372 sig.WriteByte(typeIndex);
2373 // Bootlegged from method ref
2374 sig.WriteByte((byte)callConv);
2375 MetaData.CompressNum (numPars + numOptPars, sig);
2376 retType.TypeSig (sig);
2377 for (int i=0; i < numPars; i++) {
2378 parList[i].TypeSig (sig);
2381 sig.WriteByte (0x41); // Write the sentinel
2382 for (int i=0; i < numOptPars; i++) {
2383 optParList[i].TypeSig (sig);
2388 internal sealed override void BuildTables(MetaData md)
2391 MemoryStream sig = new MemoryStream();
2393 sigIx = md.AddToBlobHeap(sig.ToArray());
2397 internal sealed override uint Size(MetaData md)
2399 return md.BlobIndexSize();
2402 internal sealed override void Write(FileImage output)
2404 output.BlobIndex(sigIx);
2407 internal sealed override uint GetCodedIx(CIx code) { return 0x1B; }
2412 /* Classes for Arrays */
2415 /// The IL Array type
2417 public abstract class Array : Type {
2419 protected Type elemType;
2420 protected MetaData metaData;
2421 protected string cnameSpace, cname;
2423 internal Array(Type eType, byte TypeId) : base(TypeId)
2426 tabIx = MDTable.TypeSpec;
2431 /// Single dimensional array with zero lower bound
2433 public class ZeroBasedArray : Array {
2436 /// Create a new array - elementType[]
2438 /// <param name="elementType">the type of the array elements</param>
2439 public ZeroBasedArray(Type elementType) : base (elementType, PrimitiveType.SZArray.GetTypeIndex ()) { }
2441 internal sealed override void TypeSig(MemoryStream str)
2443 str.WriteByte(typeIndex);
2444 elemType.TypeSig(str);
2450 /// Multi dimensional array with explicit bounds
2452 public class BoundArray : Array {
2458 /// Create a new multi dimensional array type
2459 /// eg. elemType[1..5,3..10,5,,] would be
2460 /// new BoundArray(elemType,5,[1,3,0],[5,10,4])
2462 /// <param name="elementType">the type of the elements</param>
2463 /// <param name="dimensions">the number of dimensions</param>
2464 /// <param name="loBounds">lower bounds of dimensions</param>
2465 /// <param name="sizes">sizes for the dimensions</param>
2466 public BoundArray(Type elementType, uint dimensions, int[] loBounds,
2467 int[] sizes) : base (elementType,0x14)
2469 numDims = dimensions;
2470 lowerBounds = loBounds;
2475 /// Create a new multi dimensional array type
2476 /// eg. elemType[5,10,20] would be new BoundArray(elemType,3,[5,10,20])
2478 /// <param name="elementType">the type of the elements</param>
2479 /// <param name="dimensions">the number of dimensions</param>
2480 /// <param name="size">the sizes of the dimensions</param>
2481 public BoundArray(Type elementType, uint dimensions, int[] size)
2482 : base (elementType,0x14)
2484 numDims = dimensions;
2489 /// Create a new multi dimensional array type
2490 /// eg. elemType[,,] would be new BoundArray(elemType,3)
2492 /// <param name="elementType">the type of the elements</param>
2493 /// <param name="dimensions">the number of dimensions</param>
2494 public BoundArray(Type elementType, uint dimensions)
2495 : base (elementType,0x14)
2497 numDims = dimensions;
2500 internal sealed override void TypeSig(MemoryStream str)
2502 str.WriteByte(typeIndex);
2503 elemType.TypeSig(str);
2504 MetaData.CompressNum(numDims,str);
2505 if ((sizes != null) && (sizes.Length > 0)) {
2507 MetaData.CompressNum((uint)sizes.Length,str);
2508 for (int i=0; i < sizes.Length; i++) {
2509 MetaData.CompressNum((uint)sizes[i],str);
2511 } else str.WriteByte(0);
2512 if ((lowerBounds != null) && (lowerBounds.Length > 0)) {
2513 MetaData.CompressNum((uint)lowerBounds.Length,str);
2514 for (int i=0; i < lowerBounds.Length; i++) {
2515 CompressSignedNum (lowerBounds[i],str);
2517 } else str.WriteByte(0);
2519 private void CompressSignedNum (int val, MemoryStream str)
2521 uint uval = (uint) val;
2528 /* Map the signed number to an unsigned number in two ways.
2530 fval: left-rotated 2's complement representation
2531 sval: map the signed number to unsigned as follows: 0 -> 0, -1 -> 1, 1 -> 2, -2 -> 3, 2 -> 4, ....
2532 the mapping is: x -> 2*|x| - signbit(x)
2534 uint fval = (uval << 1) | sign;
2535 int sval = (val << 1) - sign;
2537 /* An overly clever transformation:
2539 a. sval is used to determine the number of bytes in the compressed representation.
2540 b. fval is truncated to the appropriate number of bits and output using the
2541 normal unsigned-int compressor.
2543 However, or certain values, the truncated fval doesn't carry enough information to round trip.
2545 (fval & 0x3FFF) <= 0x7F => compressor emits 1 byte, not 2 => there is aliasing of values
2547 So, we use full 4 bytes to encode such values.
2549 LAMESPEC: The Microsoft implementation doesn't appear to handle this subtle case.
2550 e.g., it ends up encoding -8192 as the byte 0x01, which decodes to -64
2553 MetaData.CompressNum (fval & 0x7F, str);
2554 else if (sval <= 0x3FFF && (fval & 0x3FFF) > 0x7F)
2555 MetaData.CompressNum (fval & 0x3FFF, str);
2556 else if (sval <= 0x1FFFFFFF && (fval & 0x1FFFFFFF) > 0x3FFF)
2557 MetaData.CompressNum (fval & 0x1FFFFFFF, str);
2559 /* FIXME: number cannot be represented. Report a warning. */
2560 // throw new Exception ("cannot represent signed value" + -val);
2561 MetaData.CompressNum (fval, str);
2568 /* Empty interface for grouping TypeRef's possible ResolutionScope
2569 namely : Module, ModuleRef, AssemblyRef and TypeRef */
2570 public interface IResolutionScope {
2573 /**************************************************************************/
2575 /// Base class for scopes (extended by Module, ModuleRef, Assembly, AssemblyRef)
2577 public abstract class ResolutionScope : MetaDataElement, IResolutionScope {
2579 protected uint nameIx = 0;
2580 protected MetaData metaData;
2581 protected string name;
2583 internal ResolutionScope(string name, MetaData md)
2587 nameIx = md.AddToStringsHeap(name);
2590 internal string GetName() { return name; }
2594 /**************************************************************************/
2596 /// Descriptor for THIS assembly (.assembly)
2598 public class Assembly : ResolutionScope {
2600 ushort majorVer, minorVer, buildNo, revisionNo;
2603 uint keyIx = 0, cultIx = 0;
2604 bool hasPublicKey = false;
2606 internal Assembly(string name, MetaData md) : base(name,md)
2608 tabIx = MDTable.Assembly;
2612 /// Add details about THIS assembly
2614 /// <param name="majVer">Major Version</param>
2615 /// <param name="minVer">Minor Version</param>
2616 /// <param name="bldNo">Build Number</param>
2617 /// <param name="revNo">Revision Number</param>
2618 /// <param name="key">Hash Key</param>
2619 /// <param name="hash">Hash Algorithm</param>
2620 /// <param name="cult">Culture</param>
2621 public void AddAssemblyInfo(int majVer, int minVer, int bldNo, int revNo,
2622 byte[] key, uint hash, string cult)
2624 majorVer = (ushort)majVer;
2625 minorVer = (ushort)minVer;
2626 buildNo = (ushort)bldNo;
2627 revisionNo = (ushort)revNo;
2629 hasPublicKey = (key != null);
2630 keyIx = metaData.AddToBlobHeap(key);
2631 cultIx = metaData.AddToStringsHeap(cult);
2635 /// Add an attribute to THIS assembly
2637 /// <param name="aa">assembly attribute</param>
2638 public void AddAssemblyAttr(AssemAttr aa)
2643 internal sealed override uint Size(MetaData md)
2645 return 16 + md.BlobIndexSize() + 2 * md.StringsIndexSize();
2648 internal sealed override void Write(FileImage output)
2650 // Console.WriteLine("Writing assembly element with nameIx of " + nameIx + " at file offset " + output.Seek(0,SeekOrigin.Current));
2651 output.Write((uint)hashAlgId);
2652 output.Write(majorVer);
2653 output.Write(minorVer);
2654 output.Write(buildNo);
2655 output.Write(revisionNo);
2656 output.Write(flags);
2657 output.BlobIndex(keyIx);
2658 output.StringsIndex(nameIx);
2659 output.StringsIndex(cultIx);
2662 internal sealed override uint GetCodedIx(CIx code)
2665 case (CIx.HasCustomAttr) : return 14;
2666 case (CIx.HasDeclSecurity) : return 2;
2671 internal bool HasPublicKey {
2672 get { return hasPublicKey; }
2676 /**************************************************************************/
2678 /// Descriptor for THIS module
2680 public class Module : ResolutionScope, IExternRef {
2685 internal Module(string name, MetaData md) : base(name,md)
2687 mvid = Guid.NewGuid();
2688 mvidIx = md.AddToGUIDHeap(mvid);
2689 tabIx = MDTable.Module;
2693 get { return mvid; }
2696 public ClassRef AddClass(string nsName, string name)
2698 ClassRef aClass = new ClassRef (nsName, name, metaData);
2699 metaData.AddToTable (MDTable.TypeRef, aClass);
2700 aClass.SetParent (this);
2704 public ClassRef AddValueClass(string nsName, string name)
2706 ClassRef aClass = AddClass (nsName, name);
2707 aClass.MakeValueClass (ValueClass.ValueType);
2711 internal sealed override uint Size(MetaData md)
2713 return 2 + md.StringsIndexSize() + 3 * md.GUIDIndexSize();
2716 internal sealed override void Write(FileImage output)
2718 output.Write((short)0);
2719 output.StringsIndex(nameIx);
2720 output.GUIDIndex(mvidIx);
2721 output.GUIDIndex(0);
2722 output.GUIDIndex(0);
2725 internal sealed override uint GetCodedIx(CIx code)
2728 case (CIx.HasCustomAttr) : return 7;
2729 case (CIx.ResolutionScope) : return 0;
2734 /**************************************************************************/
2736 /// Descriptor for another module in THIS assembly
2738 public class ModuleRef : ResolutionScope, IExternRef {
2740 internal ModuleRef(MetaData md, string name) : base(name,md)
2742 tabIx = MDTable.ModuleRef;
2746 /// Add a class to this external module. This is a class declared in
2747 /// another module of THIS assembly.
2749 /// <param name="nsName">name space name</param>
2750 /// <param name="name">class name</param>
2751 /// <returns>a descriptor for this class in another module</returns>
2752 public ClassRef AddClass(string nsName, string name)
2754 ClassRef aClass = new ClassRef(nsName,name,metaData);
2755 metaData.AddToTable(MDTable.TypeRef,aClass);
2756 aClass.SetParent(this);
2761 /// Make a file descriptor to correspond to this module. The file
2762 /// descriptor will have the same name as the module descriptor
2764 /// <param name="hashBytes">the hash of the file</param>
2765 /// <param name="hasMetaData">the file contains metadata</param>
2766 /// <param name="entryPoint">the program entry point is in this file</param>
2767 /// <returns>a descriptor for the file which contains this module</returns>
2768 public FileRef MakeFile(byte[] hashBytes, bool hasMetaData, bool entryPoint)
2770 FileRef file = new FileRef(nameIx,hashBytes,hasMetaData,entryPoint,metaData);
2771 metaData.AddToTable(MDTable.File,file);
2776 /// Add a value class to this module. This is a class declared in
2777 /// another module of THIS assembly.
2779 /// <param name="nsName">name space name</param>
2780 /// <param name="name">class name</param>
2781 /// <returns></returns>
2782 public ClassRef AddValueClass(string nsName, string name)
2784 ClassRef aClass = new ClassRef(nsName,name,metaData);
2785 metaData.AddToTable(MDTable.TypeRef,aClass);
2786 aClass.SetParent(this);
2787 aClass.MakeValueClass(ValueClass.ValueType);
2792 /// Add a class which is declared public in this external module of
2793 /// THIS assembly. This class will be exported from this assembly.
2794 /// The ilasm syntax for this is .extern class
2796 /// <param name="attrSet">attributes of the class to be exported</param>
2797 /// <param name="nsName">name space name</param>
2798 /// <param name="name">external class name</param>
2799 /// <param name="declFile">the file where the class is declared</param>
2800 /// <param name="isValueClass">is this class a value type?</param>
2801 /// <returns>a descriptor for this external class</returns>
2802 public ExternClassRef AddExternClass(TypeAttr attrSet, string nsName,
2803 string name, FileRef declFile,
2804 bool isValueClass) {
2805 ExternClassRef cRef = new ExternClassRef(attrSet,nsName,name,declFile,metaData);
2806 metaData.AddToTable(MDTable.TypeRef,cRef);
2807 cRef.SetParent(this);
2808 if (isValueClass) cRef.MakeValueClass(ValueClass.ValueType);
2813 /// Add a "global" method in another module
2815 /// <param name="name">method name</param>
2816 /// <param name="retType">return type</param>
2817 /// <param name="pars">method parameter types</param>
2818 /// <returns>a descriptor for this method in anther module</returns>
2819 public MethodRef AddMethod(string name, Type retType, Type[] pars)
2821 MethodRef meth = new MethodRef(this,name,retType,pars,false,null, 0);
2822 metaData.AddToTable(MDTable.MemberRef,meth);
2827 /// Add a vararg method to this class
2829 /// <param name="name">method name</param>
2830 /// <param name="retType">return type</param>
2831 /// <param name="pars">parameter types</param>
2832 /// <param name="optPars">optional param types for this vararg method</param>
2833 /// <returns>a descriptor for this method</returns>
2834 public MethodRef AddVarArgMethod(string name, Type retType,
2835 Type[] pars, Type[] optPars) {
2836 MethodRef meth = new MethodRef(this,name,retType,pars,true,optPars, 0);
2837 metaData.AddToTable(MDTable.MemberRef,meth);
2842 /// Add a field in another module
2844 /// <param name="name">field name</param>
2845 /// <param name="fType">field type</param>
2846 /// <returns>a descriptor for this field in another module</returns>
2847 public FieldRef AddField(string name, Type fType)
2849 FieldRef field = new FieldRef(this,name,fType);
2850 metaData.AddToTable(MDTable.MemberRef,field);
2854 internal sealed override uint Size(MetaData md)
2856 return md.StringsIndexSize();
2859 internal sealed override void Write(FileImage output)
2861 output.StringsIndex(nameIx);
2864 internal sealed override uint GetCodedIx(CIx code)
2867 case (CIx.HasCustomAttr) : return 12;
2868 case (CIx.MemberRefParent) : return 2;
2869 case (CIx.ResolutionScope) : return 1;
2876 #region Classes for Constants
2878 /// Descriptor for a constant value
2880 public abstract class Constant {
2881 protected uint size = 0;
2882 protected Type type;
2883 protected uint blobIndex;
2884 protected bool addedToBlobHeap = false;
2886 internal Constant() { }
2888 internal virtual uint GetBlobIndex(MetaData md) { return 0; }
2890 internal uint GetSize() { return size; }
2892 internal byte GetTypeIndex() { return type.GetTypeIndex(); }
2894 internal virtual void Write(BinaryWriter bw) { }
2898 /// Descriptor for a constant value
2900 public abstract class DataConstant : Constant {
2901 private uint dataOffset = 0;
2903 internal DataConstant() { }
2905 public uint DataOffset {
2906 get { return dataOffset; }
2907 set { dataOffset = value; }
2913 /// Boolean constant
2915 public class BoolConst : Constant {
2919 /// Create a new boolean constant with the value "val"
2921 /// <param name="val">value of this boolean constant</param>
2922 public BoolConst(bool val)
2926 type = PrimitiveType.Boolean;
2929 internal sealed override uint GetBlobIndex(MetaData md)
2931 if (!addedToBlobHeap) {
2932 if (val) blobIndex = md.AddToBlobHeap((sbyte)1);
2933 else blobIndex = md.AddToBlobHeap((sbyte)0);
2934 addedToBlobHeap = true;
2939 internal sealed override void Write(BinaryWriter bw)
2941 if (val) bw.Write((sbyte)1);
2942 else bw.Write((sbyte)0);
2947 public class ByteArrConst : DataConstant {
2950 public ByteArrConst(byte[] val)
2952 type = PrimitiveType.String;
2954 size = (uint)val.Length;
2958 get { return type; }
2959 set { type = value; }
2962 internal sealed override uint GetBlobIndex(MetaData md)
2964 if (!addedToBlobHeap) {
2965 blobIndex = md.AddToBlobHeap(val);
2966 addedToBlobHeap = true;
2971 internal sealed override void Write(BinaryWriter bw)
2978 public class CharConst : Constant {
2981 public CharConst(char val)
2985 type = PrimitiveType.Char;
2988 internal sealed override uint GetBlobIndex(MetaData md)
2990 if (!addedToBlobHeap) {
2991 blobIndex = md.AddToBlobHeap(val);
2992 addedToBlobHeap = true;
2997 internal sealed override void Write(BinaryWriter bw)
3004 public class FloatConst : DataConstant {
3007 public FloatConst(float val)
3011 type = PrimitiveType.Float32;
3014 internal sealed override uint GetBlobIndex(MetaData md)
3016 if (!addedToBlobHeap) {
3017 blobIndex = md.AddToBlobHeap(val);
3018 addedToBlobHeap = true;
3023 internal sealed override void Write(BinaryWriter bw)
3030 public class DoubleConst : DataConstant {
3033 public DoubleConst(double val)
3037 type = PrimitiveType.Float64;
3040 internal sealed override uint GetBlobIndex(MetaData md)
3042 if (!addedToBlobHeap) {
3043 blobIndex = md.AddToBlobHeap(val);
3044 addedToBlobHeap = true;
3049 internal sealed override void Write(BinaryWriter bw)
3056 public class IntConst : DataConstant {
3059 public IntConst(sbyte val)
3063 type = PrimitiveType.Int8;
3066 public IntConst(short val)
3070 type = PrimitiveType.Int16;
3073 public IntConst(int val)
3077 type = PrimitiveType.Int32;
3080 public IntConst(long val)
3084 type = PrimitiveType.Int64;
3087 internal sealed override uint GetBlobIndex(MetaData md)
3089 if (!addedToBlobHeap) {
3091 case (1) : blobIndex = md.AddToBlobHeap((sbyte)val); break;
3092 case (2) : blobIndex = md.AddToBlobHeap((short)val); break;
3093 case (4) : blobIndex = md.AddToBlobHeap((int)val); break;
3094 default : blobIndex = md.AddToBlobHeap(val); break;
3096 addedToBlobHeap = true;
3101 internal sealed override void Write(BinaryWriter bw)
3104 case (1) : bw.Write((sbyte)val); break;
3105 case (2) : bw.Write((short)val); break;
3106 case (4) : bw.Write((int)val); break;
3107 default : bw.Write(val); break;
3113 public class UIntConst : Constant {
3116 public UIntConst(byte val)
3120 type = PrimitiveType.UInt8;
3122 public UIntConst(ushort val)
3126 type = PrimitiveType.UInt16;
3128 public UIntConst(uint val)
3132 type = PrimitiveType.UInt32;
3134 public UIntConst(ulong val)
3138 type = PrimitiveType.UInt64;
3141 internal sealed override uint GetBlobIndex(MetaData md)
3143 if (!addedToBlobHeap) {
3145 case (1) : blobIndex = md.AddToBlobHeap((byte)val); break;
3146 case (2) : blobIndex = md.AddToBlobHeap((ushort)val); break;
3147 case (4) : blobIndex = md.AddToBlobHeap((uint)val); break;
3148 default : blobIndex = md.AddToBlobHeap(val); break;
3150 addedToBlobHeap = true;
3155 internal sealed override void Write(BinaryWriter bw)
3158 case (1) : bw.Write((byte)val); break;
3159 case (2) : bw.Write((ushort)val); break;
3160 case (4) : bw.Write((uint)val); break;
3161 default : bw.Write(val); break;
3167 public class StringConst : DataConstant {
3170 public StringConst(string val)
3173 size = (uint)val.Length; // need to add null ??
3174 type = PrimitiveType.String;
3177 internal sealed override uint GetBlobIndex(MetaData md)
3179 if (!addedToBlobHeap) {
3180 byte [] b = Encoding.Unicode.GetBytes (val);
3181 blobIndex = md.AddToBlobHeap(b);
3182 addedToBlobHeap = true;
3187 internal sealed override void Write(BinaryWriter bw)
3194 public class NullConst : Constant {
3199 type = PrimitiveType.Class;
3202 internal sealed override uint GetBlobIndex(MetaData md)
3204 if (!addedToBlobHeap) {
3205 blobIndex = md.AddToBlobHeap((int)0);
3206 addedToBlobHeap = true;
3211 internal sealed override void Write(BinaryWriter bw)
3218 public class AddressConstant : DataConstant {
3221 public AddressConstant(DataConstant dConst)
3225 type = PrimitiveType.TypedRef;
3228 internal sealed override void Write(BinaryWriter bw)
3230 ((FileImage)bw).WriteDataRVA(data.DataOffset);
3235 public class RepeatedConstant : DataConstant {
3239 public RepeatedConstant(DataConstant dConst, int repeatCount)
3242 repCount = (uint)repeatCount;
3243 int[] sizes = new int[1];
3244 sizes[0] = repeatCount;
3245 type = new BoundArray(type,1,sizes);
3246 size = data.GetSize() * repCount;
3249 internal sealed override void Write(BinaryWriter bw)
3251 for (int i=0; i < repCount; i++) {
3258 public class ArrayConstant : DataConstant {
3259 DataConstant[] dataVals;
3261 public ArrayConstant(DataConstant[] dVals)
3264 for (int i=0; i < dataVals.Length; i++) {
3265 size += dataVals[i].GetSize();
3269 internal sealed override void Write(BinaryWriter bw)
3271 for (int i=0; i < dataVals.Length; i++) {
3272 dataVals[i].Write(bw);
3278 public class ClassType : Constant {
3282 public ClassType(string className)
3285 type = PrimitiveType.ClassType;
3288 public ClassType(Class classDesc)
3291 type = PrimitiveType.ClassType;
3294 internal override void Write(BinaryWriter bw)
3296 if (name == null) name = desc.TypeName();
3304 /**************************************************************************/
3306 /// Descriptor for a custom modifier of a type (modopt or modreq)
3309 public class CustomModifiedType : Type {
3315 /// Create a new custom modifier for a type
3317 /// <param name="type">the type to be modified</param>
3318 /// <param name="cmod">the modifier</param>
3319 /// <param name="cmodType">the type reference to be associated with the type</param>
3320 public CustomModifiedType(Type type, CustomModifier cmod, Class cmodType)
3324 this.cmodType = cmodType;
3327 internal sealed override void TypeSig(MemoryStream str)
3329 str.WriteByte(typeIndex);
3330 MetaData.CompressNum(cmodType.TypeDefOrRefToken(),str);
3336 /**************************************************************************/
3338 /// Base class for Event and Property descriptors
3341 public class Feature : MetaDataElement {
3343 internal enum MethodType : ushort { Setter = 0x01, Getter, Other = 0x04, AddOn = 0x08,
3344 RemoveOn = 0x10, Fire = 0x20 }
3346 private static readonly int INITSIZE = 5;
3347 private static readonly ushort specialName = 0x200;
3348 private static readonly ushort rtSpecialName = 0x400;
3350 protected ClassDef parent;
3351 protected ushort flags = 0;
3352 protected string name;
3353 protected int tide = 0;
3354 protected uint nameIx;
3355 protected MethodSemantics[] methods = new MethodSemantics[INITSIZE];
3357 internal Feature(string name, ClassDef par)
3363 internal void AddMethod(MethodDef meth, MethodType mType)
3365 if (tide >= methods.Length) {
3366 int len = methods.Length;
3367 MethodSemantics[] mTmp = methods;
3368 methods = new MethodSemantics[len * 2];
3369 for (int i=0; i < len; i++) {
3370 methods[i] = mTmp[i];
3373 methods[tide++] = new MethodSemantics(mType,meth,this);
3377 /// Set the specialName attribute for this Event or Property
3379 public void SetSpecialName()
3381 flags |= specialName;
3385 /// Set the RTSpecialName attribute for this Event or Property
3387 public void SetRTSpecialName()
3389 flags |= rtSpecialName;
3394 /**************************************************************************/
3396 /// Descriptor for an event
3398 public class Event : Feature {
3402 internal Event(string name, Type eType, ClassDef parent)
3403 : base(name, parent)
3406 tabIx = MDTable.Event;
3410 /// Add the addon method to this event
3412 /// <param name="addon">the addon method</param>
3413 public void AddAddon(MethodDef addon)
3415 AddMethod(addon,MethodType.AddOn);
3419 /// Add the removeon method to this event
3421 /// <param name="removeOn">the removeon method</param>
3422 public void AddRemoveOn(MethodDef removeOn)
3424 AddMethod(removeOn,MethodType.RemoveOn);
3428 /// Add the fire method to this event
3430 /// <param name="fire">the fire method</param>
3431 public void AddFire(MethodDef fire)
3433 AddMethod(fire,MethodType.Fire);
3437 /// Add another method to this event
3439 /// <param name="other">the method to be added</param>
3440 public void AddOther(MethodDef other)
3442 AddMethod(other,MethodType.Other);
3445 internal sealed override void BuildTables(MetaData md)
3448 nameIx = md.AddToStringsHeap(name);
3449 for (int i=0; i < tide; i++) {
3450 md.AddToTable(MDTable.MethodSemantics,methods[i]);
3455 internal sealed override uint Size(MetaData md)
3457 return 2 + md.StringsIndexSize() + md.CodedIndexSize(CIx.TypeDefOrRef);
3460 internal sealed override void Write(FileImage output)
3462 output.Write(flags);
3463 output.StringsIndex(nameIx);
3464 output.WriteCodedIndex(CIx.TypeDefOrRef,eventType);
3467 internal sealed override uint GetCodedIx(CIx code)
3470 case (CIx.HasCustomAttr) : return 10;
3471 case (CIx.HasSemantics) : return 0;
3478 /**************************************************************************/
3480 /// Descriptor for the Property of a class
3482 public class Property : Feature {
3484 private static readonly byte PropertyTag = 0x8;
3485 private bool instance;
3486 MethodDef getterMeth;
3487 ConstantElem constVal;
3488 uint typeBlobIx = 0;
3493 internal Property(string name, Type retType, Type[] pars, ClassDef parent) : base(name, parent)
3495 returnType = retType;
3497 if (pars != null) numPars = (uint)pars.Length;
3498 tabIx = MDTable.Property;
3502 /// Add a set method to this property
3504 /// <param name="setter">the set method</param>
3505 public void AddSetter(MethodDef setter)
3507 AddMethod(setter,MethodType.Setter);
3511 /// Add a get method to this property
3513 /// <param name="getter">the get method</param>
3514 public void AddGetter(MethodDef getter)
3516 AddMethod(getter,MethodType.Getter);
3517 getterMeth = getter;
3521 /// Add another method to this property
3523 /// <param name="other">the method</param>
3524 public void AddOther(MethodDef other)
3526 AddMethod(other,MethodType.Other);
3530 /// Add an initial value for this property
3532 /// <param name="constVal">the initial value for this property</param>
3533 public void AddInitValue(Constant constVal)
3535 this.constVal = new ConstantElem(this,constVal);
3538 public void SetInstance (bool isInstance)
3540 this.instance = isInstance;
3543 internal sealed override void BuildTables(MetaData md)
3546 nameIx = md.AddToStringsHeap(name);
3547 MemoryStream sig = new MemoryStream();
3548 byte tag = PropertyTag;
3552 MetaData.CompressNum(numPars,sig);
3553 returnType.TypeSig(sig);
3554 for (int i=0; i < numPars; i++) {
3555 parList[i].TypeSig(sig);
3557 typeBlobIx = md.AddToBlobHeap(sig.ToArray());
3558 for (int i=0; i < tide; i++) {
3559 md.AddToTable(MDTable.MethodSemantics,methods[i]);
3561 if (constVal != null) {
3562 md.AddToTable(MDTable.Constant,constVal);
3563 constVal.BuildTables(md);
3568 internal sealed override uint Size(MetaData md)
3570 return 2 + md.StringsIndexSize() + md.BlobIndexSize();
3573 internal sealed override void Write(FileImage output)
3575 output.Write(flags);
3576 output.StringsIndex(nameIx);
3577 output.BlobIndex(typeBlobIx);
3580 internal sealed override uint GetCodedIx(CIx code)
3583 case (CIx.HasCustomAttr) : return 9;
3584 case (CIx.HasConst) : return 2;
3585 case (CIx.HasSemantics) : return 1;
3592 /**************************************************************************/
3594 /// Base class for field/methods (member of a class)
3596 public abstract class Member : MetaDataElement {
3598 protected string name;
3599 protected uint nameIx = 0, sigIx = 0;
3601 internal Member(string memName)
3604 tabIx = MDTable.MemberRef;
3609 /*****************************************************************************/
3611 /// Descriptor for a field of a class
3614 public abstract class Field : Member {
3616 protected static readonly byte FieldSig = 0x6;
3618 protected Type type;
3620 internal Field(string pfName, Type pfType) : base(pfName)
3626 /**************************************************************************/
3628 /// Descriptor for a field defined in a class of THIS assembly/module
3630 public class FieldDef : Field {
3632 //private static readonly uint PInvokeImpl = 0x2000;
3633 private static readonly ushort HasFieldRVA = 0x100;
3634 private static readonly ushort HasDefault = 0x8000;
3637 ConstantElem constVal;
3639 FieldMarshal marshalInfo;
3642 internal FieldDef(string name, Type fType) : base(name,fType)
3644 tabIx = MDTable.Field;
3647 internal FieldDef(FieldAttr attrSet, string name, Type fType) : base(name, fType)
3649 flags = (ushort)attrSet;
3650 tabIx = MDTable.Field;
3654 /// Add an attribute(s) to this field
3656 /// <param name="fa">the attribute(s) to be added</param>
3657 public void AddFieldAttr(FieldAttr fa)
3659 flags |= (ushort)fa;
3663 /// Add a value for this field
3665 /// <param name="val">the value for the field</param>
3666 public void AddValue(Constant val)
3668 constVal = new ConstantElem(this,val);
3669 flags |= HasDefault;
3673 /// Add an initial value for this field (at dataLabel) (.data)
3675 /// <param name="val">the value for the field</param>
3676 /// <param name="repeatVal">the number of repetitions of this value</param>
3677 public void AddDataValue(DataConstant val)
3679 flags |= HasFieldRVA;
3680 rva = new FieldRVA(this,val);
3684 /// Set the offset of the field. Used for sequential or explicit classes.
3687 /// <param name="offs">field offset</param>
3688 public void SetOffset(uint offs)
3690 layout = new FieldLayout(this,offs);
3694 /// Set the marshalling info for a field
3696 /// <param name="mInf"></param>
3697 public void SetMarshalInfo(NativeType marshallType)
3699 flags |= (ushort) FieldAttr.HasFieldMarshal;
3700 marshalInfo = new FieldMarshal(this,marshallType);
3703 internal sealed override void BuildTables(MetaData md)
3706 nameIx = md.AddToStringsHeap(name);
3707 MemoryStream sig = new MemoryStream();
3708 sig.WriteByte(FieldSig);
3710 sigIx = md.AddToBlobHeap(sig.ToArray());
3712 md.AddToTable(MDTable.FieldRVA,rva);
3713 rva.BuildTables(md);
3714 } else if (constVal != null) {
3715 md.AddToTable(MDTable.Constant,constVal);
3716 constVal.BuildTables(md);
3718 if (layout != null) md.AddToTable(MDTable.FieldLayout,layout);
3719 if (marshalInfo != null) {
3720 md.AddToTable(MDTable.FieldMarshal,marshalInfo);
3721 marshalInfo.BuildTables(md);
3726 internal sealed override uint Size(MetaData md)
3728 return 2 + md.StringsIndexSize() + md.BlobIndexSize();
3731 internal sealed override void Write(FileImage output)
3733 output.Write(flags);
3734 output.StringsIndex(nameIx);
3735 output.BlobIndex(sigIx);
3738 internal sealed override uint GetCodedIx(CIx code)
3741 case (CIx.HasConst) : return 0;
3742 case (CIx.HasCustomAttr) : return 1;
3743 case (CIx.HasFieldMarshal) : return 0;
3744 case (CIx.MemberForwarded) : return 0;
3751 /**************************************************************************/
3753 /// Descriptor for a field of a class defined in another assembly/module
3755 public class FieldRef : Field {
3757 MetaDataElement parent;
3759 internal FieldRef(MetaDataElement paren, string name, Type fType) : base(name, fType)
3764 internal sealed override void BuildTables(MetaData md)
3767 nameIx = md.AddToStringsHeap(name);
3768 MemoryStream sig = new MemoryStream();
3769 sig.WriteByte(FieldSig);
3771 sigIx = md.AddToBlobHeap(sig.ToArray());
3775 internal sealed override uint Size(MetaData md)
3777 return md.CodedIndexSize(CIx.MemberRefParent) + md.StringsIndexSize() + md.BlobIndexSize();
3780 internal sealed override void Write(FileImage output)
3782 output.WriteCodedIndex(CIx.MemberRefParent,parent);
3783 output.StringsIndex(nameIx);
3784 output.BlobIndex(sigIx);
3787 internal sealed override uint GetCodedIx(CIx code) { return 6; }
3791 /**************************************************************************/
3793 /// Base class for Method Descriptors
3796 public abstract class Method : Member {
3798 internal Method (string methName) : base (methName)
3801 public abstract void AddCallConv(CallConv cconv);
3802 internal abstract void TypeSig(MemoryStream sig);
3803 internal abstract uint GetSigIx(MetaData md);
3806 /**************************************************************************/
3808 /// Descriptor for a method defined in THIS assembly/module
3812 public class MethodDef : Method {
3814 private static readonly ushort PInvokeImpl = 0x2000;
3815 //private static readonly uint UnmanagedExport = 0x0008;
3816 // private static readonly byte LocalSigByte = 0x7;
3817 uint parIx = 0, textOffset = 0;
3818 private CallConv callConv = CallConv.Default;
3819 private int gen_param_count;
3822 CILInstructions code;
3826 ushort methFlags = 0, implFlags = 0;
3827 int maxStack = 0, numPars = 0;
3828 bool entryPoint = false;
3830 ArrayList varArgSigList;
3831 ImplMap pinvokeImpl;
3834 internal MethodDef (MetaData md, string name, Param ret_param, Param [] pars)
3835 : this (md, 0, 0, name, ret_param, pars)
3839 internal MethodDef (MetaData md, MethAttr mAttrSet, ImplAttr iAttrSet, string name,
3840 Param ret_param, Param [] pars)
3843 methFlags = (ushort)mAttrSet;
3844 implFlags = (ushort)iAttrSet;
3845 this.ret_param = ret_param;
3848 if (parList != null)
3849 numPars = parList.Length;
3850 tabIx = MDTable.Method;
3853 internal Param[] GetPars()
3858 internal override uint GetSigIx(MetaData md)
3860 MemoryStream sig = new MemoryStream();
3862 return md.AddToBlobHeap(sig.ToArray());
3865 public override void AddCallConv(CallConv cconv)
3871 /// Add some attributes to this method descriptor
3873 /// <param name="ma">the attributes to be added</param>
3874 public void AddMethAttribute(MethAttr ma)
3876 methFlags |= (ushort)ma;
3880 /// Add some implementation attributes to this method descriptor
3882 /// <param name="ia">the attributes to be added</param>
3883 public void AddImplAttribute(ImplAttr ia)
3885 implFlags |= (ushort)ia;
3888 public void AddPInvokeInfo(ModuleRef scope, string methName,
3889 PInvokeAttr callAttr) {
3890 pinvokeImpl = new ImplMap((ushort)callAttr,this,methName,scope);
3891 methFlags |= PInvokeImpl;
3895 /// Add a named generic type parameter
3897 public GenericParameter AddGenericParameter (short index, string name)
3899 return AddGenericParameter (index, name, 0);
3903 /// Add a named generic type parameter with attributes
3905 public GenericParameter AddGenericParameter (short index, string name, GenericParamAttributes attr)
3907 GenericParameter gp = new GenericParameter (this, metaData, index, name, attr);
3908 metaData.AddToTable (MDTable.GenericParam, gp);
3914 /// Set the maximum stack height for this method
3916 /// <param name="maxStack">the maximum height of the stack</param>
3917 public void SetMaxStack(int maxStack)
3919 this.maxStack = maxStack;
3923 /// Add local variables to this method
3925 /// <param name="locals">the locals to be added</param>
3926 /// <param name="initLocals">are locals initialised to default values</param>
3927 public void AddLocals(Local[] locals, bool initLocals)
3929 this.locals = locals;
3930 this.initLocals = initLocals;
3933 /* Add Marshal info for return type */
3934 public void AddRetTypeMarshallInfo (NativeType marshallType)
3936 ret_param.AddMarshallInfo (marshallType);
3940 /// Mark this method as having an entry point
3942 public void DeclareEntryPoint()
3948 /// Create a code buffer for this method to add the IL instructions to
3950 /// <returns>a buffer for this method's IL instructions</returns>
3951 public CILInstructions CreateCodeBuffer()
3953 code = new CILInstructions(metaData);
3958 /// Make a method reference descriptor for this method to be used
3959 /// as a callsite signature for this vararg method
3961 /// <param name="optPars">the optional pars for the vararg method call</param>
3962 /// <returns></returns>
3963 public MethodRef MakeVarArgSignature(Type[] optPars)
3965 Type[] pars = new Type[numPars];
3966 MethodRef varArgSig;
3967 for (int i=0; i < numPars; i++) {
3968 pars[i] = parList[i].GetParType();
3970 varArgSig = new MethodRef (this, name, ret_param.GetParType (), pars, true, optPars, 0);
3972 if (varArgSigList == null)
3973 varArgSigList = new ArrayList ();
3974 varArgSigList.Add (varArgSig);
3978 internal sealed override void TypeSig(MemoryStream sig)
3980 sig.WriteByte((byte)callConv);
3981 if ((callConv & CallConv.Generic) == CallConv.Generic)
3982 MetaData.CompressNum ((uint) gen_param_count, sig);
3983 MetaData.CompressNum((uint)numPars,sig);
3985 ret_param.seqNo = 0;
3986 ret_param.TypeSig (sig);
3987 for (ushort i=0; i < numPars; i++) {
3988 parList[i].seqNo = (ushort)(i+1);
3989 parList[i].TypeSig(sig);
3993 internal sealed override void BuildTables(MetaData md)
3996 if (pinvokeImpl != null) {
3997 md.AddToTable(MDTable.ImplMap,pinvokeImpl);
3998 pinvokeImpl.BuildTables(md);
4000 if (entryPoint) md.SetEntryPoint(this);
4002 if (locals != null) {
4003 localSig = new LocalSig(locals);
4004 md.AddToTable(MDTable.StandAloneSig,localSig);
4005 localSig.BuildTables(md);
4006 locToken = localSig.Token();
4009 code.CheckCode(locToken,initLocals,maxStack);
4010 textOffset = md.AddCode(code);
4012 nameIx = md.AddToStringsHeap(name);
4013 sigIx = GetSigIx(md);
4014 parIx = md.TableIndex(MDTable.Param);
4015 if (ret_param.HasMarshalInfo || ret_param.HasCustomAttr) {
4016 md.AddToTable(MDTable.Param, ret_param);
4017 ret_param.BuildTables(md);
4019 for (int i=0; i < numPars; i++) {
4020 md.AddToTable(MDTable.Param,parList[i]);
4021 parList[i].BuildTables(md);
4023 if (varArgSigList != null) {
4024 foreach (MethodRef varArgSig in varArgSigList) {
4025 md.AddToTable(MDTable.MemberRef,varArgSig);
4026 varArgSig.BuildTables(md);
4029 // Console.WriteLine("method has " + numPars + " parameters");
4033 internal sealed override uint Size(MetaData md)
4035 return 8 + md.StringsIndexSize() + md.BlobIndexSize() + md.TableIndexSize(MDTable.Param);
4038 internal sealed override void Write(FileImage output)
4040 if (ZeroRva ()) output.Write(0);
4041 else output.WriteCodeRVA(textOffset);
4042 output.Write(implFlags);
4043 output.Write(methFlags);
4044 output.StringsIndex(nameIx);
4045 output.BlobIndex(sigIx);
4046 output.WriteIndex(MDTable.Param,parIx);
4049 internal bool ZeroRva ()
4051 return (((methFlags & (ushort)MethAttr.Abstract) != 0) ||
4052 ((implFlags & (ushort)ImplAttr.Runtime) != 0) ||
4053 ((implFlags & (ushort)ImplAttr.InternalCall) != 0) ||
4054 (pinvokeImpl != null)); // TODO: Not entirely true but works for now
4057 internal sealed override uint GetCodedIx(CIx code)
4060 case (CIx.HasCustomAttr) : return 0;
4061 case (CIx.HasDeclSecurity) : return 1;
4062 case (CIx.MemberRefParent) : return 3;
4063 case (CIx.MethodDefOrRef) : return 0;
4064 case (CIx.MemberForwarded) : return 1;
4065 case (CIx.CustomAttributeType) : return 2;
4066 case (CIx.TypeOrMethodDef) : return 1;
4072 /**************************************************************************/
4074 /// Descriptor for a method defined in another assembly/module
4076 public class MethodRef : Method {
4078 private static readonly byte Sentinel = 0x41;
4079 Type[] parList, optParList;
4080 MetaDataElement parent;
4081 uint numPars = 0, numOptPars = 0;
4082 CallConv callConv = CallConv.Default;
4084 int gen_param_count;
4086 internal MethodRef(MetaDataElement paren, string name, Type retType,
4087 Type[] pars, bool varArgMeth, Type[] optPars, int gen_param_count) : base(name)
4091 this.retType = retType;
4092 if (parList != null) numPars = (uint)parList.Length;
4094 optParList = optPars;
4095 if (optParList != null) numOptPars = (uint)optParList.Length;
4096 callConv = CallConv.Vararg;
4098 this.gen_param_count = gen_param_count;
4101 internal override uint GetSigIx(MetaData md)
4103 MemoryStream sig = new MemoryStream();
4105 return md.AddToBlobHeap(sig.ToArray());
4108 public override void AddCallConv(CallConv cconv)
4113 internal sealed override void TypeSig(MemoryStream sig)
4115 sig.WriteByte((byte)callConv);
4116 if ((callConv & CallConv.Generic) == CallConv.Generic)
4117 MetaData.CompressNum ((uint) gen_param_count, sig);
4118 MetaData.CompressNum(numPars+numOptPars,sig);
4119 retType.TypeSig(sig);
4120 for (int i=0; i < numPars; i++) {
4121 parList[i].TypeSig(sig);
4123 if (numOptPars > 0) {
4124 sig.WriteByte(Sentinel);
4125 for (int i=0; i < numOptPars; i++) {
4126 optParList[i].TypeSig(sig);
4131 internal sealed override void BuildTables(MetaData md)
4134 nameIx = md.AddToStringsHeap(name);
4135 sigIx = GetSigIx(md);
4139 internal sealed override uint Size(MetaData md)
4141 return md.CodedIndexSize(CIx.MemberRefParent) + md.StringsIndexSize() + md.BlobIndexSize();
4144 internal sealed override void Write(FileImage output)
4146 output.WriteCodedIndex(CIx.MemberRefParent,parent);
4147 output.StringsIndex(nameIx);
4148 output.BlobIndex(sigIx);
4151 internal sealed override uint GetCodedIx(CIx code)
4154 case (CIx.HasCustomAttr) : return 6;
4155 case (CIx.MethodDefOrRef) : return 1;
4156 case (CIx.CustomAttributeType) : return 3;
4164 /**************************************************************************/
4166 /// Descriptors for native types used for marshalling
4168 public class NativeType {
4169 public static readonly NativeType Void = new NativeType(0x01);
4170 public static readonly NativeType Boolean = new NativeType(0x02);
4171 public static readonly NativeType Int8 = new NativeType(0x03);
4172 public static readonly NativeType UInt8 = new NativeType(0x04);
4173 public static readonly NativeType Int16 = new NativeType(0x05);
4174 public static readonly NativeType UInt16 = new NativeType(0x06);
4175 public static readonly NativeType Int32 = new NativeType(0x07);
4176 public static readonly NativeType UInt32 = new NativeType(0x08);
4177 public static readonly NativeType Int64 = new NativeType(0x09);
4178 public static readonly NativeType UInt64 = new NativeType(0x0A);
4179 public static readonly NativeType Float32 = new NativeType(0x0B);
4180 public static readonly NativeType Float64 = new NativeType(0x0C);
4181 public static readonly NativeType Currency = new NativeType(0x0F);
4182 public static readonly NativeType BStr = new NativeType(0x13);
4183 public static readonly NativeType LPStr = new NativeType(0x14);
4184 public static readonly NativeType LPWStr = new NativeType(0x15);
4185 public static readonly NativeType LPTStr = new NativeType(0x16);
4186 public static readonly NativeType FixedSysString = new NativeType(0x17);
4187 public static readonly NativeType IUnknown = new NativeType(0x19);
4188 public static readonly NativeType IDispatch = new NativeType(0x1A);
4189 public static readonly NativeType Struct = new NativeType(0x1B);
4190 public static readonly NativeType Interface = new NativeType(0x1C);
4191 public static readonly NativeType Int = new NativeType(0x1F);
4192 public static readonly NativeType UInt = new NativeType(0x20);
4193 public static readonly NativeType ByValStr = new NativeType(0x22);
4194 public static readonly NativeType AnsiBStr = new NativeType(0x23);
4195 public static readonly NativeType TBstr = new NativeType(0x24);
4196 public static readonly NativeType VariantBool = new NativeType(0x25);
4197 public static readonly NativeType FuncPtr = new NativeType(0x26);
4198 public static readonly NativeType AsAny = new NativeType(0x28);
4199 public static readonly NativeType LPStruct = new NativeType(0x2b);
4200 public static readonly NativeType Error = new NativeType(0x2d);
4202 protected byte typeIndex;
4204 internal NativeType(byte tyIx) { typeIndex = tyIx; }
4205 internal byte GetTypeIndex() { return typeIndex; }
4207 internal virtual byte[] ToBlob()
4209 byte[] bytes = new byte[1];
4210 bytes[0] = GetTypeIndex();
4216 public class FixedSysString : NativeType {
4220 public FixedSysString (uint size) : base (NativeType.FixedSysString.GetTypeIndex ())
4225 internal override byte [] ToBlob ()
4227 MemoryStream str = new MemoryStream ();
4228 str.WriteByte (GetTypeIndex ());
4229 MetaData.CompressNum (size, str);
4230 return str.ToArray ();
4235 public class NativeArray : NativeType {
4237 NativeType elemType;
4238 int numElem = -1, parNum = -1, elemMult = -1;
4240 public NativeArray(NativeType elemType) : this (elemType, -1, -1, -1)
4242 this.elemType = elemType;
4245 /* public NativeArray(NativeType elemType, int len) : base(0x2A) {
4246 this.elemType = elemType;
4251 public NativeArray(NativeType elemType, int numElem, int parNumForLen, int elemMult) : base(0x2A)
4253 this.elemType = elemType;
4254 this.numElem = numElem;
4255 parNum = parNumForLen;
4256 this.elemMult = elemMult;
4259 public NativeArray(NativeType elemType, int numElem, int parNumForLen)
4260 : this (elemType, numElem, parNumForLen, -1)
4264 internal override byte[] ToBlob()
4266 MemoryStream str = new MemoryStream();
4267 str.WriteByte(GetTypeIndex());
4268 if (elemType == null) str.WriteByte(0x50); // no info (MAX)
4269 else str.WriteByte(elemType.GetTypeIndex());
4271 /* see : mono/metadata/metadata.c:mono_metadata_parse_marshal_spec
4272 * LAMESPEC: Older spec versions say elemMult comes before
4273 * len. Newer spec versions don't talk about elemMult at
4274 * all, but csc still emits it, and it is used to distinguish
4275 * between parNum being 0, and parNum being omitted.
4280 return str.ToArray ();
4282 MetaData.CompressNum((uint) parNum,str);
4283 if (numElem != -1) {
4284 MetaData.CompressNum ((uint) numElem, str);
4286 // <native_type> [ int32 ]
4287 MetaData.CompressNum((uint) elemMult,str);
4288 //else <native_type> [ int32 + int32 ]
4289 } else if (elemMult != -1) {
4290 // When can this occur ?
4291 MetaData.CompressNum (0, str);
4292 MetaData.CompressNum((uint) elemMult,str);
4294 //else <native_type> [ + int32 ]
4296 return str.ToArray();
4301 public class SafeArray : NativeType {
4303 SafeArrayType elemType;
4306 public SafeArray() : base(0x1D)
4310 public SafeArray(SafeArrayType elemType) : base(0x1D)
4312 this.elemType = elemType;
4316 internal override byte[] ToBlob()
4318 byte[] bytes = new byte[hasElemType ? 2 : 1];
4319 bytes[0] = GetTypeIndex();
4321 bytes[1] = (byte)elemType;
4327 public class FixedArray : NativeType {
4331 //public FixedArray(NativeType elemType, int numElems) : base(0x1E) {
4332 public FixedArray(int numElems) : base(0x1E)
4334 //this.elemType = elemType;
4335 numElem = (uint)numElems;
4338 internal override byte[] ToBlob()
4340 MemoryStream str = new MemoryStream();
4341 str.WriteByte(GetTypeIndex());
4342 MetaData.CompressNum(numElem,str);
4344 fixed array [5] lpstr [2]
4345 This format is not supported by ilasm 1.1.4322.2032,
4346 but is supported by 2.0.5125..
4347 ilasm 1.1 only supports "fixed array [5]"
4348 if (elemType == null) str.WriteByte(0x50); // no info (MAX)
4349 else str.WriteByte(elemType.GetTypeIndex());*/
4351 return str.ToArray();
4356 public class CustomMarshaller : NativeType {
4359 string marshallerName;
4362 public CustomMarshaller(string typeNameOrGUID, string marshallerName,
4363 string optCookie) : base(0x2C)
4365 typeName = typeNameOrGUID;
4366 this.marshallerName = marshallerName;
4370 public CustomMarshaller(string marshallerName, string optCookie)
4371 :this (null, marshallerName, optCookie)
4375 internal override byte[] ToBlob()
4377 MemoryStream str = new MemoryStream();
4378 BinaryWriter bw = new BinaryWriter(str,new UTF8Encoding());
4379 bw.Write(GetTypeIndex());
4380 //Native type name & unmanaged type - unused
4381 //See mono/metadata/metadata.c : mono_metadata_parse_marshal_spec
4382 bw.Write ((byte) 0); // Native Type name, unused
4383 bw.Write ((byte) 0); // Unmanaged type, unused
4384 if (marshallerName != null) {
4385 MetaData.CompressNum ((uint)marshallerName.Length, str);
4386 bw.Write(marshallerName.ToCharArray());
4388 bw.Write ((byte) 0);
4390 if (cookie != null) {
4391 MetaData.CompressNum ((uint)cookie.Length, str);
4392 bw.Write(cookie.ToCharArray());
4394 bw.Write ((byte) 0);
4397 return str.ToArray();
4401 /**************************************************************************/
4403 /// Descriptor for the Primitive types defined in IL
4405 public class PrimitiveType : Type {
4407 private string name;
4408 private int systemTypeIndex;
4409 public static int NumSystemTypes = 18;
4411 public static readonly PrimitiveType Void = new PrimitiveType(0x01,"Void",0);
4412 public static readonly PrimitiveType Boolean = new PrimitiveType(0x02,"Boolean",1);
4413 public static readonly PrimitiveType Char = new PrimitiveType(0x03,"Char",2);
4414 public static readonly PrimitiveType Int8 = new PrimitiveType(0x04,"SByte",3);
4415 public static readonly PrimitiveType UInt8 = new PrimitiveType(0x05,"Byte",4);
4416 public static readonly PrimitiveType Int16 = new PrimitiveType(0x06,"Int16",5);
4417 public static readonly PrimitiveType UInt16 = new PrimitiveType(0x07,"UInt16",6);
4418 public static readonly PrimitiveType Int32 = new PrimitiveType(0x08,"Int32",7);
4419 public static readonly PrimitiveType UInt32 = new PrimitiveType(0x09,"UInt32",8);
4420 public static readonly PrimitiveType Int64 = new PrimitiveType(0x0A,"Int64",9);
4421 public static readonly PrimitiveType UInt64 = new PrimitiveType(0x0B,"UInt64",10);
4422 public static readonly PrimitiveType Float32 = new PrimitiveType(0x0C,"Single",11);
4423 public static readonly PrimitiveType Float64 = new PrimitiveType(0x0D,"Double",12);
4424 public static readonly PrimitiveType String = new PrimitiveType(0x0E,"String",13);
4425 internal static readonly PrimitiveType Class = new PrimitiveType(0x12);
4426 internal static readonly PrimitiveType Var = new PrimitiveType(0x13);
4427 internal static readonly PrimitiveType GenericInst = new PrimitiveType(0x15);
4428 public static readonly PrimitiveType TypedRef = new PrimitiveType(0x16,"TypedReference",14);
4429 public static readonly PrimitiveType IntPtr = new PrimitiveType(0x18,"IntPtr",15);
4430 public static readonly PrimitiveType UIntPtr = new PrimitiveType(0x19,"UIntPtr",16);
4431 public static readonly PrimitiveType Object = new PrimitiveType(0x1C,"Object",17);
4432 internal static readonly PrimitiveType ClassType = new PrimitiveType(0x50);
4433 internal static readonly PrimitiveType SZArray = new PrimitiveType(0x1D);
4434 internal static readonly PrimitiveType MVar = new PrimitiveType(0x1E);
4435 internal static readonly PrimitiveType ValueType = new PrimitiveType(0x11, "ValueType", 18);
4436 public static readonly PrimitiveType NativeInt = IntPtr;
4437 public static readonly PrimitiveType NativeUInt = UIntPtr;
4439 internal PrimitiveType(byte typeIx) : base(typeIx) { }
4441 internal PrimitiveType(byte typeIx, string name, int STIx) : base(typeIx)
4444 this.systemTypeIndex = STIx;
4447 internal string GetName() { return name; }
4449 internal int GetSystemTypeIx() { return systemTypeIndex; }
4451 internal sealed override void TypeSig(MemoryStream str)
4453 str.WriteByte(typeIndex);
4456 internal override MetaDataElement GetTypeSpec(MetaData md)
4458 TypeSpec tS = md.GetPrimitiveTypeSpec(systemTypeIndex);
4460 tS = new TypeSpec(this,md);
4461 md.SetPrimitiveTypeSpec(systemTypeIndex,tS);
4462 md.AddToTable(MDTable.TypeSpec,tS);
4469 /**************************************************************************/
4471 /// Descriptor for an pointer (type * or type &)
4473 public abstract class PtrType : Type {
4477 internal PtrType(Type bType, byte typeIx) : base(typeIx)
4480 tabIx = MDTable.TypeSpec;
4483 internal sealed override void TypeSig(MemoryStream str)
4485 str.WriteByte(typeIndex);
4486 baseType.TypeSig(str);
4490 /**************************************************************************/
4492 /// Descriptor for a managed pointer (type & or byref)
4495 public class ManagedPointer : PtrType {
4498 /// Create new managed pointer to baseType
4500 /// <param name="bType">the base type of the pointer</param>
4501 public ManagedPointer(Type baseType) : base(baseType,0x10) { }
4504 /**************************************************************************/
4506 /// Descriptor for an unmanaged pointer (type *)
4508 public class UnmanagedPointer : PtrType {
4511 /// Create a new unmanaged pointer to baseType
4513 /// <param name="baseType">the base type of the pointer</param>
4514 public UnmanagedPointer(Type baseType) : base(baseType, 0x0F) { }
4518 /**************************************************************************/
4520 public interface IExternRef {
4521 ClassRef AddClass(string nsName, string name);
4522 ClassRef AddValueClass(string nsName, string name);
4526 /// A reference to an external assembly (.assembly extern)
4528 public class AssemblyRef : ResolutionScope, IExternRef {
4530 private ushort major, minor, build, revision;
4531 uint flags, keyIx, hashIx, cultIx;
4532 bool hasVersion = false, isKeyToken = false;
4536 internal AssemblyRef(MetaData md, string name) : base(name,md)
4538 tabIx = MDTable.AssemblyRef;
4541 public void AddAssemblyAttr (AssemAttr aa)
4547 /// Add version information about this external assembly
4549 /// <param name="majVer">Major Version</param>
4550 /// <param name="minVer">Minor Version</param>
4551 /// <param name="bldNo">Build Number</param>
4552 /// <param name="revNo">Revision Number</param>
4553 public void AddVersionInfo(int majVer, int minVer, int bldNo, int revNo)
4555 major = (ushort)majVer;
4556 minor = (ushort)minVer;
4557 build = (ushort)bldNo;
4558 revision = (ushort)revNo;
4563 /// Add the hash value for this external assembly
4565 /// <param name="hash">bytes of the hash value</param>
4566 public void AddHash(byte[] hash)
4568 hashIx = metaData.AddToBlobHeap(hash);
4572 /// Set the culture for this external assembly
4574 /// <param name="cult">the culture string</param>
4575 public void AddCulture(string cult)
4577 cultIx = metaData.AddToStringsHeap(cult);
4582 /// Add the full public key for this external assembly
4584 /// <param name="key">bytes of the public key</param>
4585 public void AddKey(byte[] key)
4587 flags |= 0x0001; // full public key
4589 keyIx = metaData.AddToBlobHeap(key);
4593 /// Add the public key token (low 8 bytes of the public key)
4595 /// <param name="key">low 8 bytes of public key</param>
4596 public void AddKeyToken(byte[] key)
4598 keyIx = metaData.AddToBlobHeap(key);
4604 /// Add a class to this external assembly
4606 /// <param name="nsName">name space name</param>
4607 /// <param name="name">class name</param>
4608 /// <returns></returns>
4609 public virtual ClassRef AddClass(string nsName, string name)
4611 ClassRef aClass = new ClassRef(nsName,name,metaData);
4612 metaData.AddToTable(MDTable.TypeRef,aClass);
4613 aClass.SetParent(this);
4618 /// Add a value class to this external assembly
4620 /// <param name="nsName">name space name</param>
4621 /// <param name="name">class name</param>
4622 /// <returns></returns>
4623 public virtual ClassRef AddValueClass(string nsName, string name)
4625 ClassRef aClass = new ClassRef(nsName,name,metaData);
4626 metaData.AddToTable(MDTable.TypeRef,aClass);
4627 aClass.SetParent(this);
4628 aClass.MakeValueClass(ValueClass.ValueType);
4632 internal string TypeName()
4634 string result = name;
4636 result = result + ", Version=" + major + "." + minor + "." +
4637 build + "." + revision;
4638 if (keyBytes != null) {
4639 string tokenStr = "=";
4640 if (isKeyToken) tokenStr = "Token=";
4641 result = result + ", PublicKey" + tokenStr;
4642 for (int i=0; i < keyBytes.Length; i++) {
4643 result = result + Hex.Byte(keyBytes[i]);
4646 if (culture != null)
4647 result = result + ", Culture=" + culture;
4651 internal sealed override uint Size(MetaData md)
4653 return 12 + 2 * md.StringsIndexSize() + 2 * md.BlobIndexSize();
4656 internal sealed override void Write(FileImage output)
4658 output.Write(major);
4659 output.Write(minor);
4660 output.Write(build);
4661 output.Write(revision);
4662 output.Write(flags);
4663 output.BlobIndex(keyIx);
4664 output.StringsIndex(nameIx);
4665 output.StringsIndex(cultIx);
4666 output.BlobIndex(hashIx);
4669 internal sealed override uint GetCodedIx(CIx code)
4672 case (CIx.ResolutionScope) : return 2;
4673 case (CIx.HasCustomAttr) : return 15;
4674 case (CIx.Implementation) : return 1;
4681 /**************************************************************************/
4683 /// Descriptor for a class defined in System (mscorlib)
4685 internal class SystemClass : ClassRef {
4687 PrimitiveType elemType;
4689 internal SystemClass(PrimitiveType eType, AssemblyRef paren, MetaData md)
4690 : base("System",eType.GetName(),md) {
4695 internal override sealed MetaDataElement GetTypeSpec(MetaData md)
4697 if (typeSpec == null) typeSpec = (TypeSpec)elemType.GetTypeSpec(md);
4702 internal sealed override void TypeSig(MemoryStream str)
4704 str.WriteByte(elemType.GetTypeIndex());
4709 /**************************************************************************/
4711 /// The assembly for mscorlib.
4713 public sealed class MSCorLib : AssemblyRef {
4715 private static readonly int valueTypeIx = 18;
4716 private readonly string systemName = "System";
4717 private Class[] systemClasses = new Class[valueTypeIx+2];
4718 private PrimitiveType[] systemTypes = new PrimitiveType[valueTypeIx];
4720 private static int[] specialNames = {
4721 PrimitiveType.Void.GetName().GetHashCode(),
4722 PrimitiveType.Boolean.GetName().GetHashCode(),
4723 PrimitiveType.Char.GetName().GetHashCode(),
4724 PrimitiveType.Int8.GetName().GetHashCode(),
4725 PrimitiveType.UInt8.GetName().GetHashCode(),
4726 PrimitiveType.Int16.GetName().GetHashCode(),
4727 PrimitiveType.UInt16.GetName().GetHashCode(),
4728 PrimitiveType.Int32.GetName().GetHashCode(),
4729 PrimitiveType.UInt32.GetName().GetHashCode(),
4730 PrimitiveType.Int64.GetName().GetHashCode(),
4731 PrimitiveType.UInt64.GetName().GetHashCode(),
4732 PrimitiveType.Float32.GetName().GetHashCode(),
4733 PrimitiveType.Float64.GetName().GetHashCode(),
4734 PrimitiveType.String.GetName().GetHashCode(),
4735 PrimitiveType.TypedRef.GetName().GetHashCode(),
4736 PrimitiveType.IntPtr.GetName().GetHashCode(),
4737 PrimitiveType.UIntPtr.GetName().GetHashCode(),
4738 PrimitiveType.Object.GetName().GetHashCode(),
4739 PrimitiveType.ValueType.GetName ().GetHashCode(),
4740 "Enum".GetHashCode()
4743 internal MSCorLib(MetaData md) : base(md,"mscorlib")
4745 if (!PEFile.IsMSCorlib)
4746 md.AddToTable(MDTable.AssemblyRef,this);
4747 systemTypes[PrimitiveType.Void.GetSystemTypeIx()] = PrimitiveType.Void;
4748 systemTypes[PrimitiveType.Boolean.GetSystemTypeIx()] = PrimitiveType.Boolean;
4749 systemTypes[PrimitiveType.Char.GetSystemTypeIx()] = PrimitiveType.Char;
4750 systemTypes[PrimitiveType.Int8.GetSystemTypeIx()] = PrimitiveType.Int8;
4751 systemTypes[PrimitiveType.UInt8.GetSystemTypeIx()] = PrimitiveType.UInt8;
4752 systemTypes[PrimitiveType.Int16.GetSystemTypeIx()] = PrimitiveType.Int16;
4753 systemTypes[PrimitiveType.UInt16.GetSystemTypeIx()] = PrimitiveType.UInt16;
4754 systemTypes[PrimitiveType.Int32.GetSystemTypeIx()] = PrimitiveType.Int32;
4755 systemTypes[PrimitiveType.UInt32.GetSystemTypeIx()] = PrimitiveType.UInt32;
4756 systemTypes[PrimitiveType.Int64.GetSystemTypeIx()] = PrimitiveType.Int64;
4757 systemTypes[PrimitiveType.UInt64.GetSystemTypeIx()] = PrimitiveType.UInt64;
4758 systemTypes[PrimitiveType.Float32.GetSystemTypeIx()] = PrimitiveType.Float32;
4759 systemTypes[PrimitiveType.Float64.GetSystemTypeIx()] = PrimitiveType.Float64;
4760 systemTypes[PrimitiveType.IntPtr.GetSystemTypeIx()] = PrimitiveType.IntPtr;
4761 systemTypes[PrimitiveType.UIntPtr.GetSystemTypeIx()] = PrimitiveType.UIntPtr;
4762 systemTypes[PrimitiveType.String.GetSystemTypeIx()] = PrimitiveType.String;
4763 systemTypes[PrimitiveType.Object.GetSystemTypeIx()] = PrimitiveType.Object;
4764 systemTypes[PrimitiveType.TypedRef.GetSystemTypeIx()] = PrimitiveType.TypedRef;
4768 /// Add a class to the mscorlib assembly
4770 /// <param name="nsName">name space name</param>
4771 /// <param name="name">class name</param>
4772 /// <returns></returns>
4773 public override ClassRef AddClass(string nsName, string name)
4775 /* This gets called by !mscorlib, for adding references INTO mscorlib, so
4776 it should be returning ClassRef ..*/
4777 Class aClass = GetSpecialClass(nsName,name);
4778 if (aClass == null) {
4779 aClass = new ClassRef(nsName,name,metaData);
4780 metaData.AddToTable(MDTable.TypeRef,aClass);
4781 if (aClass is ClassRef)
4782 ((ClassRef) aClass).SetParent(this);
4784 //FIXME: Check for !ClassRef here?
4785 return (ClassRef) aClass;
4788 private Class GetSpecialClass(string nsName,string name)
4790 if (nsName.CompareTo(systemName) != 0) return null;
4791 int hash = name.GetHashCode();
4792 for (int i=0; i < specialNames.Length; i++) {
4793 if (hash != specialNames[i])
4795 if (systemClasses[i] == null) {
4796 if (i < valueTypeIx) {
4797 systemClasses[i] = new SystemClass(systemTypes[i],this,metaData);
4798 if ((systemTypes[i] != PrimitiveType.Object) &&
4799 (systemTypes[i] != PrimitiveType.String)) {
4800 systemClasses[i].MakeValueClass(ValueClass.ValueType);
4803 systemClasses[i] = new ClassRef(nsName,name,metaData);
4804 ((ClassRef) systemClasses[i]).SetParent(this);
4805 if (!ClassDef.IsValueType (nsName, name) && !ClassDef.IsEnum (nsName, name))
4806 systemClasses[i].MakeValueClass(ValueClass.ValueType);
4808 metaData.AddToTable(MDTable.TypeRef,systemClasses[i]);
4810 return systemClasses[i];
4815 internal void SetSpecialSystemClass (string nsName, string name, Class aClass)
4817 if (nsName != systemName) return;
4818 int hash = name.GetHashCode ();
4819 for (int i = 0; i < specialNames.Length; i++) {
4820 if (hash != specialNames [i])
4822 if (systemClasses [i] == null) {
4823 systemClasses [i] = aClass;
4828 internal Class GetSpecialSystemClass(PrimitiveType pType)
4830 int ix = pType.GetSystemTypeIx();
4831 if (systemClasses[ix] == null && !PEFile.IsMSCorlib) {
4832 systemClasses[ix] = new SystemClass(pType,this,metaData);
4833 metaData.AddToTable(MDTable.TypeRef,systemClasses[ix]);
4835 return systemClasses[ix];
4838 private ClassRef GetValueClass(string name, int hash)
4840 /* Called by MSCorLib.AddValueClass, which is called by
4841 !mscorlib, for adding ref to value class INTO mscorlib,
4842 so this should be classref */
4843 int ix = valueTypeIx;
4844 if (hash != specialNames[valueTypeIx]) ix++;
4845 if (systemClasses[ix] == null) {
4846 systemClasses[ix] = new ClassRef(systemName,name,metaData);
4847 ((ClassRef) systemClasses[ix]).SetParent(this);
4848 ((ClassRef) systemClasses[ix]).MakeValueClass(ValueClass.ValueType);
4849 metaData.AddToTable(MDTable.TypeRef,systemClasses[ix]);
4851 return (ClassRef) systemClasses[ix];
4854 internal Class ValueType()
4856 if (systemClasses[valueTypeIx] == null && !PEFile.IsMSCorlib) {
4857 ClassRef valType = new ClassRef("System","ValueType",metaData);
4858 valType.SetParent(this);
4859 valType.MakeValueClass(ValueClass.ValueType);
4860 metaData.AddToTable(MDTable.TypeRef,valType);
4861 systemClasses[valueTypeIx] = valType;
4863 return systemClasses[valueTypeIx];
4866 internal Class EnumType()
4868 /* Called by both mscorlib & !mscorlib, so can be
4869 either ClassRef or ClassDef */
4870 //systemClasses [ valueTypeIx + 1] -> System.Enum
4871 if (systemClasses[valueTypeIx + 1] == null && !PEFile.IsMSCorlib) {
4872 ClassRef valType = new ClassRef("System","Enum",metaData);
4873 valType.SetParent(this);
4874 valType.MakeValueClass(ValueClass.Enum);
4875 metaData.AddToTable(MDTable.TypeRef,valType);
4876 systemClasses[valueTypeIx + 1] = valType;
4878 return systemClasses[valueTypeIx + 1];
4882 /// Add a value class to this external assembly
4884 /// <param name="nsName">name space name</param>
4885 /// <param name="name">class name</param>
4886 /// <returns></returns>
4887 public override ClassRef AddValueClass(string nsName, string name)
4889 if (nsName.CompareTo(systemName) == 0) {
4890 int hash = name.GetHashCode();
4891 if ((hash == specialNames[valueTypeIx]) ||
4892 (hash == specialNames[valueTypeIx+1])) {
4893 return GetValueClass(name,hash);
4896 ClassRef aClass = new ClassRef(nsName,name,metaData);
4897 metaData.AddToTable(MDTable.TypeRef,aClass);
4898 aClass.SetParent(this);
4899 aClass.MakeValueClass(ValueClass.ValueType);
4905 /**************************************************************************/
4908 /// Root (20 bytes + UTF-8 Version String + quad align padding)
4909 /// StreamHeaders (8 bytes + null terminated name string + quad align padding)
4911 /// #~ (always present - holds metadata tables)
4912 /// #Strings (always present - holds identifier strings)
4913 /// #US (Userstring heap)
4914 /// #Blob (signature blobs)
4915 /// #GUID (guids for assemblies or Modules)
4917 public class MetaData {
4919 internal static readonly int[] CIxShiftMap = {2,2,5,1,2,3,1,1,1,2,3,2,1};
4920 private static readonly byte StringsHeapMask = 0x1;
4921 private static readonly byte GUIDHeapMask = 0x2;
4922 private static readonly byte BlobHeapMask = 0x4;
4923 private static readonly uint MetaDataSignature = 0x424A5342;
4924 private static readonly uint maxSmlIxSize = 0xFFFF;
4925 private static readonly uint max1BitSmlIx = 0x7FFF;
4926 private static readonly uint max2BitSmlIx = 0x3FFF;
4927 private static readonly uint max3BitSmlIx = 0x1FFF;
4928 private static readonly uint max5BitSmlIx = 0x7FF;
4929 // NOTE: version and stream name strings MUST always be quad padded
4931 private static readonly string version = "v4.0.30319\0\0";
4933 private static readonly string version = "v2.0.50727\0\0";
4935 private static readonly string version = "v1.1.4322\0\0\0";
4937 private static readonly char[] tildeName = {'#','~','\0','\0'};
4938 private static readonly char[] stringsName = {'#','S','t','r','i','n','g','s','\0','\0','\0','\0'};
4939 private static readonly char[] usName = {'#','U','S','\0'};
4940 private static readonly char[] guidName = {'#','G','U','I','D','\0','\0','\0'};
4941 private static readonly char[] blobName = {'#','B','l','o','b','\0','\0','\0'};
4942 private static readonly uint MetaDataHeaderSize = 20 + (uint)version.Length;
4943 private static readonly uint TildeHeaderSize = 24;
4944 private static readonly uint StreamHeaderSize = 8;
4945 private static readonly uint numMetaDataTables = (int)MDTable.GenericParamConstraint + 1;
4947 MetaDataStream strings, us, guid, blob;
4949 MetaDataStream[] streams = new MetaDataStream[5];
4950 uint numStreams = 5;
4951 uint tildeTide = 0, tildePadding = 0, tildeStart = 0;
4952 uint numTables = 0, resourcesSize = 0;
4953 ArrayList[] metaDataTables = new ArrayList[numMetaDataTables];
4954 ArrayList byteCodes = new ArrayList();
4955 uint codeSize = 0, codeStart, byteCodePadding = 0, metaDataSize = 0;
4956 ulong valid = 0, /*sorted = 0x000002003301FA00;*/ sorted = 0;
4957 bool[] largeIx = new bool[numMetaDataTables];
4958 bool[] lgeCIx = new bool[(int)CIx.MaxCIx];
4959 bool largeStrings = false, largeUS = false, largeGUID = false, largeBlob = false;
4960 private FileImage file;
4961 private byte heapSizes = 0;
4962 MetaDataElement entryPoint;
4963 BinaryWriter output;
4964 public MSCorLib mscorlib;
4965 private TypeSpec[] systemTypeSpecs = new TypeSpec[PrimitiveType.NumSystemTypes];
4967 private ArrayList cattr_list;
4968 private ArrayList declsec_list;
4969 ArrayList resources;
4971 internal MetaData(FileImage file)
4973 // tilde = new MetaDataStream(tildeName,false,0);
4975 strings = new MetaDataStream(stringsName,new UTF8Encoding(),true);
4976 us = new MetaDataStream(usName,new UnicodeEncoding(),true);
4977 guid = new MetaDataStream(guidName,false);
4978 blob = new MetaDataStream(blobName,true);
4979 streams[1] = strings;
4983 for (int i=0; i < numMetaDataTables; i++) {
4986 for (int i=0; i < lgeCIx.Length; i++) {
4989 mscorlib = new MSCorLib(this);
4992 internal TypeSpec GetPrimitiveTypeSpec(int ix)
4994 return systemTypeSpecs[ix];
4997 internal void SetPrimitiveTypeSpec(int ix, TypeSpec typeSpec)
4999 systemTypeSpecs[ix] = typeSpec;
5002 internal uint Size()
5004 return metaDataSize;
5007 private void CalcHeapSizes ()
5009 if (strings.LargeIx()) {
5010 largeStrings = true;
5011 heapSizes |= StringsHeapMask;
5013 if (guid.LargeIx()) {
5015 heapSizes |= GUIDHeapMask;
5017 if (blob.LargeIx()) {
5019 heapSizes |= BlobHeapMask;
5022 largeUS = us.LargeIx();
5025 internal void StreamSize(byte mask)
5030 internal uint AddToUSHeap(string str)
5032 if (str == null) return 0;
5033 return us.Add(str,true);
5036 internal uint AddToUSHeap(byte[] str)
5038 if (str == null) return 0;
5039 return us.Add (str, true);
5042 internal uint AddToStringsHeap(string str)
5044 if ((str == null) || (str.CompareTo("") == 0)) return 0;
5045 return strings.Add(str,false);
5048 internal uint AddToGUIDHeap(Guid guidNum)
5050 return guid.Add(guidNum, false);
5053 internal uint AddToBlobHeap(byte[] blobBytes)
5055 if (blobBytes == null) return 0;
5056 return blob.Add(blobBytes, true);
5059 internal uint AddToBlobHeap(byte val)
5061 return blob.Add(val, true);
5064 internal uint AddToBlobHeap(sbyte val)
5066 return blob.Add(val, true);
5069 internal uint AddToBlobHeap(ushort val)
5071 return blob.Add(val, true);
5074 internal uint AddToBlobHeap(short val)
5076 return blob.Add(val, true);
5079 internal uint AddToBlobHeap(uint val)
5081 return blob.Add(val, true);
5084 internal uint AddToBlobHeap(int val)
5086 return blob.Add(val, true);
5089 internal uint AddToBlobHeap(ulong val)
5091 return blob.Add(val, true);
5094 internal uint AddToBlobHeap(long val)
5096 return blob.Add(val, true);
5099 internal uint AddToBlobHeap(float val)
5101 return blob.Add(val, true);
5104 internal uint AddToBlobHeap(double val)
5106 return blob.Add(val, true);
5109 internal uint AddToBlobHeap(string val)
5111 return blob.Add(val,true);
5114 internal void AddCustomAttribute (CustomAttribute cattr)
5116 if (cattr_list == null)
5117 cattr_list = new ArrayList ();
5118 cattr_list.Add (cattr);
5121 internal void AddDeclSecurity (BaseDeclSecurity decl_sec)
5123 if (declsec_list == null)
5124 declsec_list = new ArrayList ();
5125 declsec_list.Add (decl_sec);
5128 private ArrayList GetTable(MDTable tableIx)
5130 int tabIx = (int)tableIx;
5131 if (metaDataTables[tabIx] == null) {
5132 metaDataTables[tabIx] = new ArrayList();
5133 valid |= ((ulong)0x1 << tabIx);
5134 // Console.WriteLine("after creating table " + tableIx + "(" + tabIx + ") valid = " + valid);
5137 return metaDataTables[tabIx];
5140 internal void AddToTable(MDTable tableIx, MetaDataElement elem)
5143 // Console.Out.WriteLine("ERROR - element already in table " + tableIx);
5146 // updates Row field of the element
5147 // Console.WriteLine("Adding element to table " + (uint)tableIx);
5148 ArrayList table = GetTable(tableIx);
5149 elem.Row = (uint)table.Count + 1;
5153 internal uint TableIndex(MDTable tableIx)
5155 if (metaDataTables[(int)tableIx] == null) return 1;
5156 return (uint)metaDataTables[(int)tableIx].Count+1;
5159 internal uint AddCode(CILInstructions byteCode)
5161 byteCodes.Add(byteCode);
5162 uint offset = codeSize + codeStart;
5163 codeSize += byteCode.GetCodeSize();
5167 internal void SetEntryPoint(MetaDataElement ep)
5172 internal uint AddResource(byte[] resBytes)
5174 if (resources == null) resources = new ArrayList ();
5175 resources.Add (resBytes);
5176 uint offset = resourcesSize;
5177 resourcesSize += (uint)resBytes.Length + 4;
5181 internal void AddData(DataConstant cVal)
5183 file.AddInitData(cVal);
5186 internal static void CompressNum(uint val, MemoryStream sig)
5189 sig.WriteByte((byte)val);
5190 } else if (val <= 0x3FFF) {
5191 byte b1 = (byte)((val >> 8) | 0x80);
5192 byte b2 = (byte)(val & FileImage.iByteMask[0]);
5196 byte b1 = (byte)((val >> 24) | 0xC0);
5197 byte b2 = (byte)((val & FileImage.iByteMask[2]) >> 16);
5198 byte b3 = (byte)((val & FileImage.iByteMask[1]) >> 8);;
5199 byte b4 = (byte)(val & FileImage.iByteMask[0]);
5207 internal uint CodeSize()
5209 return codeSize + byteCodePadding;
5212 internal uint GetResourcesSize()
5214 return resourcesSize;
5217 internal uint StringsIndexSize()
5219 if (largeStrings) return 4;
5223 internal uint GUIDIndexSize()
5225 if (largeGUID) return 4;
5229 internal uint USIndexSize()
5231 if (largeUS) return 4;
5235 internal uint BlobIndexSize()
5237 if (largeBlob) return 4;
5241 internal uint CodedIndexSize(CIx code)
5243 if (lgeCIx[(uint)code]) return 4;
5247 internal uint TableIndexSize(MDTable tabIx)
5249 if (largeIx[(uint)tabIx]) return 4;
5253 private void SetIndexSizes()
5255 for (int i=0; i < numMetaDataTables; i++) {
5256 if (metaDataTables[i] == null)
5259 uint count = (uint)metaDataTables[i].Count;
5260 if (count > maxSmlIxSize)
5263 MDTable tabIx = (MDTable)i;
5264 if (count > max5BitSmlIx) {
5265 lgeCIx[(int)CIx.HasCustomAttr] = true;
5267 if (count > max3BitSmlIx) {
5268 if ((tabIx == MDTable.TypeRef) || (tabIx == MDTable.ModuleRef) || (tabIx == MDTable.Method) || (tabIx == MDTable.TypeSpec) || (tabIx == MDTable.Field))
5269 lgeCIx[(int)CIx.CustomAttributeType] = true;
5270 if ((tabIx == MDTable.Method) || (tabIx == MDTable.MemberRef))
5271 lgeCIx[(int)CIx.MemberRefParent] = true;
5273 if (count > max2BitSmlIx) {
5274 if ((tabIx == MDTable.Field) || (tabIx == MDTable.Param) || (tabIx == MDTable.Property))
5275 lgeCIx[(int)CIx.HasConst] = true;
5276 if ((tabIx == MDTable.TypeDef) || (tabIx == MDTable.TypeRef) || (tabIx == MDTable.TypeSpec))
5277 lgeCIx[(int)CIx.TypeDefOrRef] = true;
5278 if ((tabIx == MDTable.TypeDef) || (tabIx == MDTable.Method) || (tabIx == MDTable.Assembly))
5279 lgeCIx[(int)CIx.HasDeclSecurity] = true;
5280 if ((tabIx == MDTable.File) || (tabIx == MDTable.AssemblyRef) || (tabIx == MDTable.ExportedType))
5281 lgeCIx[(int)CIx.Implementation] = true;
5282 if ((tabIx == MDTable.Module) || (tabIx == MDTable.ModuleRef) || (tabIx == MDTable.AssemblyRef) || (tabIx == MDTable.TypeRef))
5283 lgeCIx[(int)CIx.ResolutionScope] = true;
5285 if (count > max1BitSmlIx) {
5286 if ((tabIx == MDTable.Field) || (tabIx == MDTable.Param))
5287 lgeCIx[(int)CIx.HasFieldMarshal] = true;
5288 if ((tabIx == MDTable.Event) || (tabIx == MDTable.Property))
5289 lgeCIx[(int)CIx.HasSemantics] = true;
5290 if ((tabIx == MDTable.Method) || (tabIx == MDTable.MemberRef))
5291 lgeCIx[(int)CIx.MethodDefOrRef] = true;
5292 if ((tabIx == MDTable.Field) || (tabIx == MDTable.Method))
5293 lgeCIx[(int)CIx.MemberForwarded] = true;
5294 if ((tabIx == MDTable.TypeDef) || (tabIx == MDTable.Method))
5295 lgeCIx[(int)CIx.TypeOrMethodDef] = true;
5300 private void SetStreamOffsets()
5302 uint sizeOfHeaders = StreamHeaderSize + (uint)tildeName.Length;
5303 for (int i=1; i < numStreams; i++) {
5304 sizeOfHeaders += streams[i].headerSize();
5306 metaDataSize = MetaDataHeaderSize + sizeOfHeaders;
5307 tildeStart = metaDataSize;
5308 metaDataSize += tildeTide + tildePadding;
5309 for (int i=1; i < numStreams; i++) {
5310 streams[i].Start = metaDataSize;
5311 metaDataSize += streams[i].Size();
5312 streams[i].WriteDetails();
5316 internal void CalcTildeStreamSize()
5319 //tilde.SetIndexSizes(strings.LargeIx(),us.LargeIx(),guid.LargeIx(),blob.LargeIx());
5320 tildeTide = TildeHeaderSize;
5321 tildeTide += 4 * numTables;
5322 //Console.WriteLine("Tilde header + sizes = " + tildeTide);
5323 for (int i=0; i < numMetaDataTables; i++) {
5324 if (metaDataTables[i] != null) {
5325 ArrayList table = metaDataTables[i];
5326 // Console.WriteLine("Meta data table " + i + " at offset " + tildeTide);
5327 tildeTide += (uint)table.Count * ((MetaDataElement)table[0]).Size(this);
5328 // Console.WriteLine("Metadata table " + i + " has size " + table.Count);
5329 // Console.WriteLine("tildeTide = " + tildeTide);
5332 if ((tildeTide % 4) != 0) tildePadding = 4 - (tildeTide % 4);
5333 //Console.WriteLine("tildePadding = " + tildePadding);
5336 internal void WriteTildeStream(FileImage output)
5338 output.Seek(0,SeekOrigin.Current);
5339 output.Write((uint)0); // Reserved
5341 output.Write((byte)2); // MajorVersion
5342 output.Write((byte)0); // MinorVersion
5344 output.Write((byte)1); // MajorVersion
5345 output.Write((byte)0); // MinorVersion
5347 output.Write(heapSizes);
5348 output.Write((byte)1); // Reserved
5349 output.Write(valid);
5350 output.Write(sorted);
5352 for (int i=0; i < numMetaDataTables; i++) {
5353 if (metaDataTables[i] != null) {
5354 uint count = (uint)metaDataTables[i].Count;
5355 output.Write(count);
5359 output.Seek(0,SeekOrigin.Current);
5360 // Console.WriteLine("Starting metaData tables at " + tabStart);
5361 for (int i=0; i < numMetaDataTables; i++) {
5362 if (metaDataTables[i] != null) {
5363 // Console.WriteLine("Starting metaData table " + i + " at " + (output.Seek(0,SeekOrigin.Current) - startTilde));
5364 ArrayList table = metaDataTables[i];
5365 for (int j=0; j < table.Count; j++) {
5366 ((MetaDataElement)table[j]).Write(output);
5370 // Console.WriteLine("Writing padding at " + output.Seek(0,SeekOrigin.Current));
5371 for (int i=0; i < tildePadding; i++) output.Write((byte)0);
5374 private void BuildTable(ArrayList table)
5376 if (table == null) return;
5377 for (int j=0; j < table.Count; j++) {
5378 ((MetaDataElement)table[j]).BuildTables(this);
5382 private void SortTable (ArrayList mTable)
5384 if (mTable == null) return;
5386 for (int i=0; i < mTable.Count; i++) {
5387 ((MetaDataElement)mTable[i]).Row = (uint)i+1;
5391 internal void BuildMetaData(uint codeStartOffset)
5393 codeStart = codeStartOffset;
5394 BuildTable(metaDataTables[(int)MDTable.TypeDef]);
5395 BuildTable(metaDataTables[(int)MDTable.TypeSpec]);
5396 BuildTable(metaDataTables[(int)MDTable.MemberRef]);
5398 BuildTable(metaDataTables[(int)MDTable.GenericParam]);
5399 BuildTable(metaDataTables[(int)MDTable.MethodSpec]);
5400 BuildTable(metaDataTables[(int)MDTable.GenericParamConstraint]);
5402 BuildTable(metaDataTables[(int)MDTable.ManifestResource]);
5404 if (cattr_list != null) {
5405 foreach (CustomAttribute cattr in cattr_list)
5406 cattr.BuildTables (this);
5409 if (declsec_list != null) {
5410 foreach (BaseDeclSecurity decl_sec in declsec_list)
5411 decl_sec.BuildTables (this);
5414 /* for (int i=0; i < metaDataTables.Length; i++) {
5415 ArrayList table = metaDataTables[i];
5416 if (table != null) {
5417 for (int j=0; j < table.Count; j++) {
5418 ((MetaDataElement)table[j]).BuildTables(this);
5425 for (int i=1; i < numStreams; i++) {
5426 streams[i].EndStream();
5428 CalcTildeStreamSize();
5430 byteCodePadding = NumToAlign(codeSize,4);
5431 if (entryPoint != null) file.SetEntryPoint(entryPoint.Token());
5433 // Check ordering of specific tables
5434 // Constant, CustomAttribute, FieldMarshal, DeclSecurity, MethodSemantics
5435 // ImplMap, GenericParam
5436 // Need to load GenericParamConstraint AFTER GenericParam table in correct order
5438 // InterfaceImpl, ClassLayout, FieldLayout, MethodImpl, FieldRVA, NestedClass
5439 // will _ALWAYS_ be in the correct order as embedded in BuildMDTables
5441 SortTable(metaDataTables[(int)MDTable.Constant]);
5442 SortTable(metaDataTables[(int)MDTable.FieldMarshal]);
5443 SortTable(metaDataTables[(int)MDTable.DeclSecurity]);
5444 SortTable(metaDataTables[(int)MDTable.MethodSemantics]);
5445 SortTable(metaDataTables[(int)MDTable.ImplMap]);
5447 if (metaDataTables[(int)MDTable.GenericParam] != null) {
5448 SortTable(metaDataTables[(int)MDTable.GenericParam]);
5449 // Now add GenericParamConstraints
5450 /*for (int i=0; i < metaDataTables[(int)MDTable.GenericParam].Count; i++) {
5451 ((GenericParameter)metaDataTables[(int)MDTable.GenericParam][i]).AddConstraints(this);
5454 SortTable(metaDataTables[(int)MDTable.GenericParamConstraint]);
5456 SortTable(metaDataTables[(int)MDTable.InterfaceImpl]);
5457 SortTable(metaDataTables[(int)MDTable.CustomAttribute]);
5461 internal void WriteByteCodes(FileImage output)
5463 for (int i=0; i < byteCodes.Count; i++) {
5464 ((CILInstructions)byteCodes[i]).Write(output);
5466 for (int i=0; i < byteCodePadding; i++) {
5467 output.Write((byte)0);
5471 internal void WriteResources (FileImage output)
5473 if (resources == null) return;
5474 for (int i = 0; i < resources.Count; i ++) {
5475 byte [] resBytes = (byte []) resources [i];
5476 output.Write ((uint) resBytes.Length);
5477 output.Write (resBytes);
5481 internal void WriteMetaData(FileImage output)
5483 this.output = output;
5484 mdStart = output.Seek(0,SeekOrigin.Current);
5485 // Console.WriteLine("Writing metaData at " + Hex.Long(mdStart));
5486 output.Write(MetaDataSignature);
5487 output.Write((short)1); // Major Version
5488 output.Write((short)1); // Minor Version ECMA = 0, PEFiles = 1
5489 output.Write(0); // Reserved
5490 output.Write(version.Length);
5491 output.Write(version.ToCharArray()); // version string is already zero padded
5492 output.Write((short)0);
5493 output.Write((ushort)numStreams);
5494 // write tilde header
5495 output.Write(tildeStart);
5496 output.Write(tildeTide + tildePadding);
5497 output.Write(tildeName);
5498 for (int i=1; i < numStreams; i++) streams[i].WriteHeader(output);
5499 // Console.WriteLine("Writing tilde stream at " + output.Seek(0,SeekOrigin.Current) + " = " + tildeStart);
5500 WriteTildeStream(output);
5501 for (int i=1; i < numStreams; i++) streams[i].Write(output);
5502 // Console.WriteLine("Finished Writing metaData at " + output.Seek(0,SeekOrigin.Current));
5505 internal bool LargeStringsIndex() { return strings.LargeIx(); }
5506 internal bool LargeGUIDIndex() { return guid.LargeIx(); }
5507 internal bool LargeUSIndex() { return us.LargeIx(); }
5508 internal bool LargeBlobIndex() { return blob.LargeIx(); }
5510 internal bool LargeIx(MDTable tabIx) { return largeIx[(uint)tabIx]; }
5513 private uint NumToAlign(uint val, uint alignVal)
5515 if ((val % alignVal) == 0) return 0;
5516 return alignVal - (val % alignVal);
5519 internal void WriteCodedIndex(CIx code, MetaDataElement elem, FileImage output)
5523 ix = (elem.Row << CIxShiftMap[(uint)code]) | elem.GetCodedIx(code);
5524 // Console.WriteLine("coded index = " + ix + " row = " + elem.Row);
5526 // Console.WriteLine("elem for coded index is null");
5528 if (lgeCIx[(uint)code])
5531 output.Write((ushort)ix);
5536 /**************************************************************************/
5538 /// Stream in the Meta Data (#Strings, #US, #Blob and #GUID)
5541 internal class MetaDataStream : BinaryWriter {
5543 private static readonly uint StreamHeaderSize = 8;
5544 private static uint maxSmlIxSize = 0xFFFF;
5546 private uint start = 0;
5547 uint size = 0, tide = 1;
5548 bool largeIx = false;
5551 Hashtable htable = new Hashtable();
5552 Hashtable btable = new Hashtable (new ByteArrayHashCodeProvider (), new ByteArrayComparer ());
5554 internal MetaDataStream(char[] name, bool addInitByte) : base(new MemoryStream())
5556 if (addInitByte) { Write((byte)0); size = 1; }
5558 sizeOfHeader = StreamHeaderSize + (uint)name.Length;
5561 internal MetaDataStream(char[] name, System.Text.Encoding enc, bool addInitByte) : base(new MemoryStream(),enc)
5563 if (addInitByte) { Write((byte)0); size = 1; }
5565 sizeOfHeader = StreamHeaderSize + (uint)name.Length;
5569 get { return start; }
5570 set { start = value; }
5573 internal uint headerSize()
5575 // Console.WriteLine(name + " stream has headersize of " + sizeOfHeader);
5576 return sizeOfHeader;
5579 internal void SetSize(uint siz)
5584 internal uint Size()
5589 internal bool LargeIx()
5594 internal void WriteDetails()
5596 // Console.WriteLine(name + " - size = " + size);
5599 internal uint Add(string str, bool prependSize)
5601 Object val = htable[str];
5605 htable[str] = index;
5606 char[] arr = str.ToCharArray();
5607 if (prependSize) CompressNum((uint)arr.Length*2+1);
5610 size = (uint)Seek(0,SeekOrigin.Current);
5616 internal uint Add (byte[] str, bool prependSize)
5618 Object val = btable [str];
5622 btable [str] = index;
5623 if (prependSize) CompressNum ((uint) str.Length);
5625 size = (uint) Seek (0, SeekOrigin.Current);
5633 internal uint Add(Guid guid, bool prependSize)
5635 byte [] b = guid.ToByteArray ();
5636 if (prependSize) CompressNum ((uint) b.Length);
5637 Write(guid.ToByteArray());
5638 size =(uint)Seek(0,SeekOrigin.Current);
5642 internal uint Add(byte[] blob)
5645 CompressNum((uint)blob.Length);
5647 size = (uint)Seek(0,SeekOrigin.Current);
5651 internal uint Add(byte val, bool prependSize)
5654 if (prependSize) CompressNum (1);
5656 size = (uint)Seek(0,SeekOrigin.Current);
5660 internal uint Add(sbyte val, bool prependSize)
5663 if (prependSize) CompressNum (1);
5665 size = (uint)Seek(0,SeekOrigin.Current);
5669 internal uint Add(ushort val, bool prependSize)
5672 if (prependSize) CompressNum (2);
5674 size = (uint)Seek(0,SeekOrigin.Current);
5678 internal uint Add(short val, bool prependSize)
5681 if (prependSize) CompressNum (2);
5683 size = (uint)Seek(0,SeekOrigin.Current);
5687 internal uint Add(uint val, bool prependSize)
5690 if (prependSize) CompressNum (4);
5692 size = (uint)Seek(0,SeekOrigin.Current);
5696 internal uint Add(int val, bool prependSize)
5699 if (prependSize) CompressNum (4);
5701 size = (uint)Seek(0,SeekOrigin.Current);
5705 internal uint Add(ulong val, bool prependSize)
5708 if (prependSize) CompressNum (8);
5710 size = (uint)Seek(0,SeekOrigin.Current);
5714 internal uint Add(long val, bool prependSize)
5717 if (prependSize) CompressNum (8);
5719 size = (uint)Seek(0,SeekOrigin.Current);
5723 internal uint Add(float val, bool prependSize)
5726 if (prependSize) CompressNum (4);
5728 size = (uint)Seek(0,SeekOrigin.Current);
5732 internal uint Add(double val, bool prependSize)
5735 if (prependSize) CompressNum (8);
5737 size = (uint)Seek(0,SeekOrigin.Current);
5741 private void CompressNum(uint val)
5745 } else if (val < 0x3FFF) {
5746 byte b1 = (byte)((val >> 8) | 0x80);
5747 byte b2 = (byte)(val & FileImage.iByteMask[0]);
5751 byte b1 = (byte)((val >> 24) | 0xC0);
5752 byte b2 = (byte)((val & FileImage.iByteMask[2]) >> 16);
5753 byte b3 = (byte)((val & FileImage.iByteMask[1]) >> 8);;
5754 byte b4 = (byte)(val & FileImage.iByteMask[0]);
5762 private void QuadAlign()
5764 if ((size % 4) != 0) {
5765 uint pad = 4 - (size % 4);
5767 for (int i=0; i < pad; i++) {
5773 internal void EndStream()
5776 if (size > maxSmlIxSize) {
5781 internal void WriteHeader(BinaryWriter output)
5783 output.Write(start);
5788 internal virtual void Write(BinaryWriter output)
5790 // Console.WriteLine("Writing " + name + " stream at " + output.Seek(0,SeekOrigin.Current) + " = " + start);
5791 MemoryStream str = (MemoryStream)BaseStream;
5792 output.Write(str.ToArray());
5797 /**************************************************************************/
5798 class ByteArrayComparer : IComparer {
5800 public int Compare (object x, object y)
5802 byte [] a = (byte []) x;
5803 byte [] b = (byte []) y;
5806 if (b.Length != len)
5809 for (int i = 0; i < len; ++i)
5816 class ByteArrayHashCodeProvider : IHashCodeProvider {
5818 public int GetHashCode (Object key)
5820 byte [] arr = (byte []) key;
5821 int len = arr.Length;
5824 for (int i = 0; i < len; ++i)
5825 h = (h << 5) - h + arr [i];