3 using System
.Collections
;
11 /// flags for the assembly (.corflags)
13 public enum CorFlags
{CF_IL_ONLY
= 1, CF_32_BITREQUIRED
= 2,
14 CF_STRONGNAMESIGNED
= 8, CF_TRACKDEBUGDATA
= 0x10000 }
17 /// subsystem for the assembly (.subsystem)
19 public enum SubSystem
{ Native
= 1, Windows_GUI
= 2,
20 Windows_CUI
= 3, OS2_CUI
= 5, POSIX_CUI
= 7, Native_Windows
= 8,
24 /// Hash algorithms for the assembly
26 public enum HashAlgorithm { None, SHA1 }
29 /// Attributes for this assembly
31 public enum AssemAttr
{ EnableJITCompileTracking
= 0x8000,
32 DisableJITCompileOptimizer
= 0x4000}
35 /// Method call conventions
38 public enum CallConv
{ Default
, Cdecl
, Stdcall
, Thiscall
,
39 Fastcall
, Vararg
, Instance
= 0x20, Generic
= 0x10, InstanceExplicit
= 0x60 }
42 /// Type custom modifier
44 public enum CustomModifier { modreq = 0x1F, modopt }
;
47 /// Attibutes for a class
49 public enum TypeAttr
{Private
, Public
, NestedPublic
, NestedPrivate
,
50 NestedFamily
, NestedAssembly
, NestedFamAndAssem
, NestedFamOrAssem
,
51 SequentialLayout
, ExplicitLayout
= 0x10, Interface
= 0x20,
52 Abstract
= 0x80, PublicAbstract
= 0x81, Sealed
= 0x100,
53 PublicSealed
= 0x101, SpecialName
= 0x400, RTSpecialName
= 0x800,
54 Import
= 0x1000, Serializable
= 0x2000, UnicodeClass
= 0x10000,
55 AutoClass
= 0x20000, HasSecurity
= 0x40000, BeforeFieldInit
= 0x100000,
56 VisibilityMask
= 0x07 }
59 /// Attributes for a field
61 public enum FieldAttr
{Default
, Private
, FamAndAssem
, Assembly
,
62 Family
, FamOrAssem
, Public
, Static
= 0x10, PublicStatic
= 0x16,
63 Initonly
= 0x20, Literal
= 0x40, Notserialized
= 0x80,
64 SpecialName
= 0x200, RTSpecialName
= 0x400, HasFieldMarshal
= 0x1000 }
67 /// Attributes for a method
69 public enum MethAttr
{ Default
, Private
, FamAndAssem
, Assembly
,
70 Family
, FamOrAssem
, Public
, Static
= 0x0010, PublicStatic
= 0x16,
71 Final
= 0x0020, PublicStaticFinal
= 0x36, Virtual
= 0x0040,
72 PrivateVirtual
, PublicVirtual
= 0x0046, HideBySig
= 0x0080,
73 NewSlot
= 0x0100, Abstract
= 0x0400, SpecialName
= 0x0800,
74 RTSpecialName
= 0x1000, SpecialRTSpecialName
= 0x1800,
75 HasSecurity
= 0x4000, RequireSecObject
= 0x8000}
78 /// Attributes for .pinvokeimpl method declarations
80 public enum PInvokeAttr
{ nomangle
= 1, ansi
= 2, unicode
= 4, autochar
= 6,
81 lasterr
= 0x0040, winapi
= 0x0100, cdecl
= 0x0200,
82 stdcall
= 0x0300, thiscall
= 0x0400, fastcall
= 0x0500 }
85 /// Implementation attributes for a method
87 public enum ImplAttr
{ IL
, Native
, Runtime
= 0x03, Unmanaged
= 0x04,
88 ForwardRef
= 0x10, PreserveSig
= 0x0080, InternalCall
= 0x1000,
89 Synchronised
= 0x0020, Synchronized
= 0x0020, NoInLining
= 0x0008, Optil
= 0x0002}
92 /// Modes for a parameter
94 public enum ParamAttr { Default, In, Out, Opt = 16, HasDefault = 0x1000, HasFieldMarshal = 0x2000 }
99 public enum Op
{ nop
, breakOp
, ldarg_0
, ldarg_1
, ldarg_2
, ldarg_3
,
100 ldloc_0
, ldloc_1
, ldloc_2
, ldloc_3
, stloc_0
, stloc_1
, stloc_2
, stloc_3
,
101 ldnull
= 0x14, ldc_i4_m1
, ldc_i4_0
, ldc_i4_1
, ldc_i4_2
, ldc_i4_3
,
102 ldc_i4_4
, ldc_i4_5
, ldc_i4_6
, ldc_i4_7
, ldc_i4_8
, dup
= 0x25, pop
,
103 ret
= 0x2A, ldind_i1
= 0x46, ldind_u1
, ldind_i2
, ldind_u2
, ldind_i4
,
104 ldind_u4
, ldind_i8
, ldind_i
, ldind_r4
, ldind_r8
, ldind_ref
, stind_ref
,
105 stind_i1
, stind_i2
, stind_i4
, stind_i8
, stind_r4
, stind_r8
, add, sub
, mul
,
106 div
, div_un
, rem
, rem_un
, and
, or
, xor
, shl
, shr
, shr_un
, neg
, not
,
107 conv_i1
, conv_i2
, conv_i4
, conv_i8
, conv_r4
, conv_r8
, conv_u4
, conv_u8
,
108 conv_r_un
= 0x76, throwOp
= 0x7A, conv_ovf_i1_un
= 0x82, conv_ovf_i2_un
,
109 conv_ovf_i4_un
, conv_ovf_i8_un
, conf_ovf_u1_un
, conv_ovf_u2_un
,
110 conv_ovf_u4_un
, conv_ovf_u8_un
, conv_ovf_i_un
, conv_ovf_u_un
,
111 ldlen
= 0x8E, ldelem_i1
= 0x90, ldelem_u1
, ldelem_i2
, ldelem_u2
,
112 ldelem_i4
, ldelem_u4
, ldelem_i8
, ldelem_i
, ldelem_r4
, ldelem_r8
,
113 ldelem_ref
, stelem_i
, stelem_i1
, stelem_i2
, stelem_i4
, stelem_i8
, stelem_r4
= 0xA0, stelem_r8
,
114 stelem_ref
, conv_ovf_i1
= 0xb3, conv_ovf_u1
, conv_ovf_i2
, conv_ovf_u2
,
115 conv_ovf_i4
, conv_ovf_u4
, conv_ovf_i8
, conv_ovf_u8
, ckfinite
= 0xC3,
116 conv_u2
= 0xD1, conv_u1
, conv_i
, conv_ovf_i
, conv_ovf_u
, add_ovf
,
117 add_ovf_un
, mul_ovf
, mul_ovf_un
, sub_ovf
, sub_ovf_un
, endfinally
,
118 stind_i
= 0xDF, conv_u
, arglist
= 0xFE00, ceq
, cgt
, cgt_un
, clt
, clt_un
,
119 localloc
= 0xFE0F, endfilter
= 0xFE11, volatile_
= 0xFE13, tail_
,
120 cpblk
= 0xFE17, initblk
, rethrow
= 0xFE1A, refanytype
= 0xFE1D}
123 /// CIL instructions requiring an integer parameter
125 public enum IntOp
{ldarg_s
= 0x0E, ldarga_s
, starg_s
, ldloc_s
, ldloca_s
,
126 stloc_s
, ldc_i4_s
= 0x1F, ldc_i4
, ldarg
= 0xFE09,
127 ldarga
, starg
, ldloc
, ldloca
, stloc
, unaligned
= 0xFE12 }
130 /// CIL instructions requiring a field parameter
132 public enum FieldOp
{ldfld
= 0x7B, ldflda
, stfld
, ldsfld
, ldsflda
,
133 stsfld
, ldtoken
= 0xD0 }
136 /// CIL instructions requiring a method parameter
138 public enum MethodOp
{jmp
= 0x27, call
, callvirt
= 0x6F, newobj
= 0x73,
139 ldtoken
= 0xD0, ldftn
= 0xFE06, ldvirtfn
}
142 /// CIL instructions requiring a type parameter
144 public enum TypeOp
{cpobj
= 0x70, ldobj
, castclass
= 0x74, isinst
,
145 unbox
= 0x79, stobj
= 0x81, box
= 0x8C, newarr
,
146 ldelema
= 0x8F, refanyval
= 0xC2, mkrefany
= 0xC6,
147 ldtoken
= 0xD0, initobj
= 0xFE15, sizeOf
= 0xFE1C,
148 ldelem
= 0xA3, stelem
= 0xA4, unbox_any
}
151 /// CIL branch instructions
153 public enum BranchOp
{
155 br_s
= 0x2B, brfalse_s
, brtrue_s
, beq_s
, bge_s
, bgt_s
,
156 ble_s
, blt_s
, bne_un_s
, bge_un_s
, bgt_un_s
, ble_un_s
, blt_un_s
,
158 br
= 0x38, brfalse
, brtrue
, beq
, bge
, bgt
, ble
, blt
,
159 bne_un
, bge_un
, bgt_un
, ble_un
, blt_un
,
161 leave
= 0xDD, leave_s
}
164 /// Index for all the tables in the meta data
166 public enum MDTable
{ Module
, TypeRef
, TypeDef
, Field
= 0x04, Method
= 0x06,
167 Param
= 0x08, InterfaceImpl
, MemberRef
, Constant
, CustomAttribute
,
168 FieldMarshal
, DeclSecurity
, ClassLayout
, FieldLayout
, StandAloneSig
,
169 EventMap
, Event
= 0x14, PropertyMap
, Property
= 0x17, MethodSemantics
,
170 MethodImpl
, ModuleRef
, TypeSpec
, ImplMap
, FieldRVA
, Assembly
= 0x20,
171 AssemblyProcessor
, AssemblyOS
, AssemblyRef
, AssemblyRefProcessor
,
172 AssemblyRefOS
, File
, ExportedType
, ManifestResource
, NestedClass
,
173 GenericParam
, MethodSpec
, GenericParamConstraint
}
175 public enum SafeArrayType
{ int16
= 2, int32
, float32
, float64
,
176 currency
, date
, bstr
, dispatch
, error
, boolean
, variant
, unknown
,
177 Decimal
, int8
= 16, uint8
, uint16
, uint32
, Int
= 22, UInt
}
179 internal enum CIx
{ TypeDefOrRef
, HasConst
, HasCustomAttr
, HasFieldMarshal
,
180 HasDeclSecurity
, MemberRefParent
, HasSemantics
, MethodDefOrRef
,
181 MemberForwarded
, Implementation
, CustomAttributeType
, ResolutionScope
,
182 TypeOrMethodDef
, MaxCIx
}
184 internal enum MapType { eventMap, propertyMap, nestedClass }
186 public enum ValueClass { ValueType, Enum }
188 public enum GenParamType
: byte {
189 Var
= 0x13, MVar
= 0x1E
192 /* Taken from Mono.Cecil */
193 public enum SecurityAction
: short {
207 NonCasLinkDemand
= 14,
208 NonCasInheritance
= 15,
209 LinkDemandChoice
= 16,
210 InheritDemandChoice
= 17,
216 /**************************************************************************/
218 /// Base class for all Meta Data table elements
221 public abstract class MetaDataElement
: IComparable
{
222 protected ArrayList customAttributes
;
223 private uint row
= 0;
224 protected bool done
= false;
225 protected MDTable tabIx
;
226 protected bool sortTable
= false;
228 internal MetaDataElement() { }
235 if (row
== 0) row
= value;
239 internal virtual uint GetCodedIx(CIx code
) { return 0; }
242 /// Add a custom attribute to this item
244 /// <param name="ctorMeth">the constructor method for this attribute</param>
245 /// <param name="val">the byte value of the parameters</param>
246 public void AddCustomAttribute(Method ctorMeth
, byte[] val
)
248 if (customAttributes
== null) {
249 customAttributes
= new ArrayList();
251 customAttributes
.Add(new CustomAttribute(this,ctorMeth
,val
));
255 /// Add a custom attribute to this item
257 /// <param name="ctorMeth">the constructor method for this attribute</param>
258 /// <param name="val">the constant values of the parameters</param>
259 public void AddCustomAttribute(Method ctorMeth
, Constant
[] cVals
)
261 if (customAttributes
== null) {
262 customAttributes
= new ArrayList();
264 // customAttributes.Add(new CustomAttribute(this,ctorMeth,cVals));
267 internal uint Token()
269 return (((uint)tabIx
<< 24) | row
);
272 internal virtual void BuildTables(MetaData md
)
277 internal virtual uint Size(MetaData md
)
282 internal virtual void Write(FileImage output
) { }
284 internal virtual uint SortKey()
286 throw new PEFileException("Trying to sort table of " + this);
290 internal virtual uint SortKey2()
295 public int CompareTo(object obj
)
297 uint otherKey
= ((MetaDataElement
)obj
).SortKey();
298 uint thisKey
= SortKey();
300 if (thisKey
== otherKey
) {
302 otherKey
= ((MetaDataElement
)obj
).SortKey2();
303 thisKey
= SortKey2();
304 if (thisKey
== otherKey
)
306 if (thisKey
< otherKey
)
310 if (thisKey
< otherKey
) return -1;
317 /**************************************************************************/
319 /// Layout information for a class (.class [sequential | explicit])
321 internal class ClassLayout
: MetaDataElement
{
327 internal ClassLayout(int pack
, int cSize
, ClassDef par
)
329 packSize
= (ushort)pack
;
330 classSize
= (uint)cSize
;
332 tabIx
= MDTable
.ClassLayout
;
335 internal sealed override uint Size(MetaData md
)
337 return 6 + md
.TableIndexSize(MDTable
.TypeDef
);
340 internal sealed override void Write(FileImage output
)
342 output
.Write(packSize
);
343 output
.Write(classSize
);
344 output
.WriteIndex(MDTable
.TypeDef
,parent
.Row
);
349 /**************************************************************************/
351 /// Summary description for ConstantElem.
353 internal class ConstantElem
: MetaDataElement
{
355 MetaDataElement parent
;
359 internal ConstantElem(MetaDataElement parent
, Constant val
)
361 this.parent
= parent
;
363 tabIx
= MDTable
.Constant
;
367 internal override uint SortKey()
369 return (parent
.Row
<< MetaData
.CIxShiftMap
[(uint)CIx
.HasConst
])
370 | parent
.GetCodedIx(CIx
.HasConst
);
373 internal sealed override void BuildTables(MetaData md
)
376 valIx
= cValue
.GetBlobIndex(md
);
380 internal void AddToBlob(BinaryWriter bw
)
385 internal sealed override uint Size(MetaData md
)
387 return 2 + md
.CodedIndexSize(CIx
.HasConst
) + md
.BlobIndexSize();
390 internal sealed override void Write(FileImage output
)
392 output
.Write(cValue
.GetTypeIndex());
393 output
.Write((byte)0);
394 output
.WriteCodedIndex(CIx
.HasConst
,parent
);
395 output
.BlobIndex(valIx
);
399 /**************************************************************************/
401 /// Descriptor for a Custom Attribute (.custom)
404 public class CustomAttribute
: MetaDataElement
{
406 private static readonly ushort prolog
= 0x0001;
407 MetaDataElement parent
;
413 ArrayList names
, vals
;
415 internal CustomAttribute(MetaDataElement paren
, Method constrType
,
420 tabIx
= MDTable
.CustomAttribute
;
423 internal CustomAttribute(MetaDataElement paren
, Method constrType
,
427 tabIx
= MDTable
.CustomAttribute
;
431 internal override uint SortKey()
433 return (parent
.Row
<< MetaData
.CIxShiftMap
[(uint)CIx
.HasCustomAttr
])
434 | parent
.GetCodedIx(CIx
.HasCustomAttr
);
437 public void AddFieldOrProp(string name
, Constant val
)
440 names
= new ArrayList();
441 vals
= new ArrayList();
447 internal sealed override void BuildTables(MetaData md
)
449 BinaryWriter bw
= new BinaryWriter(new MemoryStream());
451 md
.AddToTable(MDTable
.CustomAttribute
, this);
452 MemoryStream str
= (MemoryStream
)bw
.BaseStream
;
453 valIx
= md
.AddToBlobHeap(str
.ToArray());
456 internal sealed override uint Size(MetaData md
)
458 return md
.CodedIndexSize(CIx
.HasCustomAttr
) + md
.CodedIndexSize(CIx
.CustomAttributeType
) + md
.BlobIndexSize();
461 internal sealed override void Write(FileImage output
)
463 output
.WriteCodedIndex(CIx
.HasCustomAttr
,parent
);
464 output
.WriteCodedIndex(CIx
.CustomAttributeType
,type
);
465 output
.BlobIndex(valIx
);
470 /**************************************************************************/
472 /// Descriptor for security permissions for a class or a method
475 public class DeclSecurity
: MetaDataElement
{
478 MetaDataElement parent
;
482 internal DeclSecurity(MetaDataElement paren
, ushort act
, byte [] val
)
486 tabIx
= MDTable
.DeclSecurity
;
490 internal override uint SortKey()
492 return (parent
.Row
<< MetaData
.CIxShiftMap
[(uint)CIx
.HasDeclSecurity
])
493 | parent
.GetCodedIx(CIx
.HasDeclSecurity
);
496 internal sealed override uint Size(MetaData md
)
498 return 2 + md
.CodedIndexSize(CIx
.HasDeclSecurity
) + md
.BlobIndexSize();
501 internal sealed override void BuildTables(MetaData md
)
504 BinaryWriter bw
= new BinaryWriter (new MemoryStream ());
506 md
.AddToTable (MDTable
.DeclSecurity
, this);
507 MemoryStream str
= (MemoryStream
)bw
.BaseStream
;
508 permissionIx
= md
.AddToBlobHeap(str
.ToArray());
513 internal sealed override void Write(FileImage output
)
515 output
.Write(action
);
516 output
.WriteCodedIndex(CIx
.HasDeclSecurity
,parent
);
517 output
.BlobIndex(permissionIx
);
522 /**************************************************************************/
524 /// Descriptor for layout information for a field
527 public class FieldLayout
: MetaDataElement
{
532 internal FieldLayout(Field field
, uint offset
)
535 this.offset
= offset
;
536 tabIx
= MDTable
.FieldLayout
;
539 internal sealed override uint Size(MetaData md
)
541 return 4 + md
.TableIndexSize(MDTable
.Field
);
544 internal sealed override void Write(FileImage output
)
546 output
.Write(offset
);
547 output
.WriteIndex(MDTable
.Field
,field
.Row
);
552 /*****************************************************************************/
554 /// Marshalling information for a field or param
556 public class FieldMarshal
: MetaDataElement
{
558 MetaDataElement field
;
562 internal FieldMarshal(MetaDataElement field
, NativeType nType
)
566 tabIx
= MDTable
.FieldMarshal
;
569 internal override uint SortKey()
571 return (field
.Row
<< MetaData
.CIxShiftMap
[(uint)CIx
.HasFieldMarshal
])
572 | field
.GetCodedIx(CIx
.HasFieldMarshal
);
575 internal sealed override void BuildTables(MetaData md
)
578 ntIx
= md
.AddToBlobHeap(nt
.ToBlob());
582 internal sealed override uint Size(MetaData md
)
584 return md
.CodedIndexSize(CIx
.HasFieldMarshal
) + md
.BlobIndexSize();
587 internal sealed override void Write(FileImage output
)
589 output
.WriteCodedIndex(CIx
.HasFieldMarshal
,field
);
590 output
.BlobIndex(ntIx
);
595 /**************************************************************************/
597 /// Descriptor for the address of a field's value in the PE file
599 public class FieldRVA
: MetaDataElement
{
604 internal FieldRVA(Field field
, DataConstant data
)
608 tabIx
= MDTable
.FieldRVA
;
611 internal sealed override void BuildTables(MetaData md
)
618 internal sealed override uint Size(MetaData md
)
620 return 4 + md
.TableIndexSize(MDTable
.Field
);
623 internal sealed override void Write(FileImage output
)
625 output
.WriteDataRVA(data
.DataOffset
);
626 output
.WriteIndex(MDTable
.Field
,field
.Row
);
631 /**************************************************************************/
633 /// Descriptor for a file referenced in THIS assembly/module (.file)
635 public class FileRef
: MetaDataElement
{
637 private static readonly uint NoMetaData
= 0x1;
638 uint nameIx
= 0, hashIx
= 0;
640 protected string name
;
642 internal FileRef(string name
, byte[] hashBytes
, bool metaData
,
643 bool entryPoint
, MetaData md
) {
644 if (!metaData
) flags
= NoMetaData
;
645 if (entryPoint
) md
.SetEntryPoint(this);
647 nameIx
= md
.AddToStringsHeap(name
);
648 hashIx
= md
.AddToBlobHeap(hashBytes
);
649 tabIx
= MDTable
.File
;
652 internal FileRef(uint nameIx
, byte[] hashBytes
, bool metaData
,
653 bool entryPoint
, MetaData md
) {
654 if (!metaData
) flags
= NoMetaData
;
655 if (entryPoint
) md
.SetEntryPoint(this);
656 this.nameIx
= nameIx
;
657 hashIx
= md
.AddToBlobHeap(hashBytes
);
658 tabIx
= MDTable
.File
;
661 internal sealed override uint Size(MetaData md
)
663 return 4 + md
.StringsIndexSize() + md
.BlobIndexSize();
666 internal sealed override void BuildTables(MetaData md
)
668 md
.AddToTable(MDTable
.File
,this);
671 internal sealed override void Write(FileImage output
)
674 output
.StringsIndex(nameIx
);
675 output
.BlobIndex(hashIx
);
678 internal sealed override uint GetCodedIx(CIx code
)
681 case (CIx
.HasCustomAttr
) : return 16;
682 case (CIx
.Implementation
) : return 0;
688 /**************************************************************************/
690 /// Descriptor for pinvoke information for a method NOT YET IMPLEMENTED
692 public class ImplMap
: MetaDataElement
{
694 private static readonly ushort NoMangle
= 0x01;
699 ModuleRef importScope
;
701 internal ImplMap(ushort flag
, Method implMeth
, string iName
, ModuleRef mScope
)
706 importScope
= mScope
;
707 tabIx
= MDTable
.ImplMap
;
708 if (iName
== null) flags
|= NoMangle
;
709 //throw(new NotYetImplementedException("PInvoke "));
712 internal override uint SortKey()
714 return (meth
.Row
<< MetaData
.CIxShiftMap
[(uint)CIx
.MemberForwarded
])
715 | meth
.GetCodedIx(CIx
.MemberForwarded
);
718 internal sealed override void BuildTables(MetaData md
)
721 iNameIx
= md
.AddToStringsHeap(importName
);
725 internal sealed override uint Size(MetaData md
)
727 return 2+ md
.CodedIndexSize(CIx
.MemberForwarded
) +
728 md
.StringsIndexSize() + md
.TableIndexSize(MDTable
.ModuleRef
);
731 internal sealed override void Write(FileImage output
)
734 output
.WriteCodedIndex(CIx
.MemberForwarded
,meth
);
735 output
.StringsIndex(iNameIx
);
736 output
.WriteIndex(MDTable
.ModuleRef
,importScope
.Row
);
741 /**************************************************************************/
743 public class GenericParameter
: MetaDataElement
{
745 MetaDataElement owner
;
751 internal GenericParameter (ClassDef owner
, MetaData metadata
,
752 short index
, string name
) : this (owner
, metadata
, index
, name
, true)
756 internal GenericParameter (MethodDef owner
, MetaData metadata
,
757 short index
, string name
) : this (owner
, metadata
, index
, name
, true)
761 private GenericParameter (MetaDataElement owner
, MetaData metadata
,
762 short index
, string name
, bool nadda
) {
764 this.metadata
= metadata
;
766 tabIx
= MDTable
.GenericParam
;
770 internal override uint SortKey()
772 return (owner
.Row
<< MetaData
.CIxShiftMap
[(uint)CIx
.TypeOrMethodDef
])
773 | owner
.GetCodedIx(CIx
.TypeOrMethodDef
);
776 internal override uint SortKey2 ()
781 public void AddConstraint (Type constraint
)
783 metadata
.AddToTable (MDTable
.GenericParamConstraint
,
784 new GenericParamConstraint (this, constraint
));
787 internal sealed override uint Size(MetaData md
)
790 md
.CodedIndexSize(CIx
.TypeOrMethodDef
) +
791 md
.StringsIndexSize ());
794 internal sealed override void BuildTables(MetaData md
)
797 nameIx
= md
.AddToStringsHeap(name
);
801 internal sealed override void Write(FileImage output
)
803 output
.Write ((short) index
);
804 output
.Write ((short) 0);
805 output
.WriteCodedIndex(CIx
.TypeOrMethodDef
, owner
);
806 output
.StringsIndex (nameIx
);
812 internal class GenericParamConstraint
: MetaDataElement
{
814 GenericParameter param
;
817 public GenericParamConstraint (GenericParameter param
, Type type
)
821 tabIx
= MDTable
.GenericParamConstraint
;
824 internal sealed override uint Size(MetaData md
)
826 return (uint) (md
.TableIndexSize(MDTable
.GenericParam
) +
827 md
.CodedIndexSize(CIx
.TypeDefOrRef
));
830 internal sealed override void Write(FileImage output
)
832 output
.WriteIndex(MDTable
.GenericParam
, param
.Row
);
833 output
.WriteCodedIndex(CIx
.TypeDefOrRef
, type
);
838 internal class MethodSpec
: Method
{
841 GenericMethodSig g_sig
;
844 internal MethodSpec (Method meth
, GenericMethodSig g_sig
) : base ("")
848 tabIx
= MDTable
.MethodSpec
;
851 internal override uint GetSigIx (MetaData md
)
853 throw new Exception ("Should not be used.");
856 public override void AddCallConv (CallConv cconv
)
858 throw new Exception ("Should not be used.");
861 internal sealed override void BuildTables (MetaData md
)
864 sidx
= g_sig
.GetSigIx (md
);
868 internal sealed override uint Size (MetaData md
)
870 return (uint) (md
.CodedIndexSize(CIx
.MethodDefOrRef
) +
871 md
.BlobIndexSize ());
874 internal sealed override void Write (FileImage output
)
876 output
.WriteCodedIndex (CIx
.MethodDefOrRef
, meth
);
877 output
.BlobIndex (sidx
);
880 internal sealed override void TypeSig (MemoryStream sig
)
882 throw new Exception ("Should not be used.");
886 /**************************************************************************/
888 /// Descriptor for interface implemented by a class
890 public class InterfaceImpl
: MetaDataElement
{
895 internal InterfaceImpl(ClassDef theClass
, Class theInterface
)
897 this.theClass
= theClass
;
898 this.theInterface
= theInterface
;
899 tabIx
= MDTable
.InterfaceImpl
;
902 internal sealed override uint Size(MetaData md
)
904 return md
.TableIndexSize(MDTable
.TypeDef
) +
905 md
.CodedIndexSize(CIx
.TypeDefOrRef
);
908 internal sealed override void Write(FileImage output
)
910 output
.WriteIndex(MDTable
.TypeDef
,theClass
.Row
);
911 output
.WriteCodedIndex(CIx
.TypeDefOrRef
,theInterface
);
914 internal sealed override uint GetCodedIx(CIx code
) { return 5; }
916 internal override uint SortKey ()
918 return (theClass
.Row
<< MetaData
.CIxShiftMap
[(uint)CIx
.TypeDefOrRef
])
919 | theClass
.GetCodedIx (CIx
.TypeDefOrRef
);
924 /**************************************************************************/
926 /// Descriptor for resources used in this PE file
929 public class ManifestResource
: MetaDataElement
{
931 public static readonly uint PublicResource
= 0x1;
932 public static readonly uint PrivateResource
= 0x2;
935 MetaDataElement rRef
;
939 byte [] resourceBytes
;
941 public ManifestResource (string name
, byte[] resBytes
, uint flags
)
943 InitResource (name
, flags
);
944 this.resourceBytes
= resBytes
;
947 public ManifestResource(string name
, uint flags
, FileRef fileRef
)
949 InitResource (name
, flags
);
953 public ManifestResource(string name
, uint flags
, FileRef fileRef
,
955 InitResource (name
, flags
);
960 public ManifestResource(string name
, uint flags
, AssemblyRef assemRef
)
962 InitResource (name
, flags
);
966 internal ManifestResource (ManifestResource mres
)
968 mrName
= mres
.mrName
;
971 fileOffset
= mres
.fileOffset
;
972 resourceBytes
= mres
.resourceBytes
;
975 private void InitResource (string name
, uint flags
)
979 tabIx
= MDTable
.ManifestResource
;
982 internal sealed override void BuildTables(MetaData md
)
985 md
.AddToTable (MDTable
.ManifestResource
, this);
986 nameIx
= md
.AddToStringsHeap(mrName
);
987 if (resourceBytes
!= null) {
989 throw new Exception("ERROR: Manifest Resource has byte value and file reference");
990 fileOffset
= md
.AddResource(resourceBytes
);
993 throw new Exception("ERROR: Manifest Resource has no implementation or value");
994 rRef
.BuildTables (md
);
1000 internal sealed override uint Size(MetaData md
)
1002 return 8 + md
.StringsIndexSize() +
1003 md
.CodedIndexSize(CIx
.Implementation
);
1006 internal sealed override void Write(FileImage output
)
1008 output
.Write(fileOffset
);
1009 output
.Write(flags
);
1010 output
.StringsIndex(nameIx
);
1011 output
.WriteCodedIndex(CIx
.Implementation
,rRef
);
1014 internal sealed override uint GetCodedIx(CIx code
) { return 18; }
1016 public string Name
{
1017 get { return mrName; }
1018 set { mrName = value; }
1022 /**************************************************************************/
1024 /// Base class for elements in the PropertyMap, EventMap and
1025 /// NestedClass MetaData tables
1027 public class MapElem
: MetaDataElement
{
1033 internal MapElem(ClassDef par
, uint elIx
, MDTable elemTab
)
1037 elemTable
= elemTab
;
1040 internal sealed override uint Size(MetaData md
)
1042 return md
.TableIndexSize(MDTable
.TypeDef
) + md
.TableIndexSize(elemTable
);
1045 internal sealed override void Write(FileImage output
)
1047 output
.WriteIndex(MDTable
.TypeDef
,parent
.Row
);
1048 output
.WriteIndex(elemTable
,elemIx
);
1052 /**************************************************************************/
1054 /// Descriptor for an overriding method (.override)
1056 public class MethodImpl
: MetaDataElement
{
1059 Method header
, body
;
1061 internal MethodImpl(ClassDef par
, Method decl
, Method bod
)
1066 tabIx
= MDTable
.MethodImpl
;
1069 internal sealed override uint Size(MetaData md
)
1071 return md
.TableIndexSize(MDTable
.TypeDef
) + 2 * md
.CodedIndexSize(CIx
.MethodDefOrRef
);
1074 internal sealed override void Write(FileImage output
)
1076 output
.WriteIndex(MDTable
.TypeDef
,parent
.Row
);
1077 output
.WriteCodedIndex(CIx
.MethodDefOrRef
,body
);
1078 output
.WriteCodedIndex(CIx
.MethodDefOrRef
,header
);
1083 /**************************************************************************/
1085 /// Descriptor for Property and Event methods
1087 public class MethodSemantics
: MetaDataElement
{
1089 Feature
.MethodType type
;
1091 Feature eventOrProp
;
1093 internal MethodSemantics(Feature
.MethodType mType
, MethodDef method
, Feature feature
)
1097 eventOrProp
= feature
;
1098 tabIx
= MDTable
.MethodSemantics
;
1101 internal override uint SortKey()
1103 return (eventOrProp
.Row
<< MetaData
.CIxShiftMap
[(uint)CIx
.HasSemantics
])
1104 | eventOrProp
.GetCodedIx (CIx
.HasSemantics
);
1107 internal sealed override uint Size(MetaData md
)
1109 return 2 + md
.TableIndexSize(MDTable
.Method
) + md
.CodedIndexSize(CIx
.HasSemantics
);
1112 internal sealed override void Write(FileImage output
)
1114 output
.Write((ushort)type
);
1115 output
.WriteIndex(MDTable
.Method
,meth
.Row
);
1116 output
.WriteCodedIndex(CIx
.HasSemantics
,eventOrProp
);
1121 /**************************************************************************/
1123 /// Descriptor for a parameter of a method defined in this assembly/module
1125 public class Param
: MetaDataElement
{
1130 internal ushort seqNo
= 0;
1132 ConstantElem defaultVal
;
1134 FieldMarshal marshalInfo
;
1137 /// Create a new parameter for a method
1139 /// <param name="mode">param mode (in, out, opt)</param>
1140 /// <param name="parName">parameter name</param>
1141 /// <param name="parType">parameter type</param>
1142 public Param(ParamAttr mode
, string parName
, Type parType
)
1146 parMode
= (ushort)mode
;
1147 tabIx
= MDTable
.Param
;
1151 /// Add a default value to this parameter
1153 /// <param name="c">the default value for the parameter</param>
1154 public void AddDefaultValue(Constant cVal
)
1156 defaultVal
= new ConstantElem(this,cVal
);
1157 parMode
|= (ushort) ParamAttr
.HasDefault
;
1161 /// Add marshalling information about this parameter
1163 public void AddMarshallInfo(NativeType marshallType
)
1165 parMode
|= (ushort) ParamAttr
.HasFieldMarshal
;
1166 marshalInfo
= new FieldMarshal(this,marshallType
);
1169 internal Type
GetParType() { return pType; }
1171 internal sealed override void BuildTables(MetaData md
)
1174 nameIx
= md
.AddToStringsHeap(pName
);
1175 if (defaultVal
!= null) {
1176 md
.AddToTable(MDTable
.Constant
,defaultVal
);
1177 defaultVal
.BuildTables(md
);
1179 if (marshalInfo
!= null) {
1180 md
.AddToTable(MDTable
.FieldMarshal
,marshalInfo
);
1181 marshalInfo
.BuildTables(md
);
1186 internal void TypeSig(MemoryStream str
)
1191 internal sealed override uint Size(MetaData md
)
1193 return 4 + md
.StringsIndexSize();
1196 internal sealed override void Write(FileImage output
)
1198 output
.Write(parMode
);
1199 output
.Write(seqNo
);
1200 output
.StringsIndex(nameIx
);
1203 internal sealed override uint GetCodedIx(CIx code
)
1206 case (CIx
.HasCustomAttr
) : return 4;
1207 case (CIx
.HasConst
) : return 1;
1208 case (CIx
.HasFieldMarshal
) : return 1;
1215 /**************************************************************************/
1216 public abstract class Signature
: MetaDataElement
{
1218 protected uint sigIx
;
1220 internal Signature()
1222 tabIx
= MDTable
.StandAloneSig
;
1225 internal sealed override uint Size(MetaData md
)
1227 return md
.BlobIndexSize();
1230 internal sealed override void Write(FileImage output
)
1232 output
.BlobIndex(sigIx
);
1235 internal sealed override uint GetCodedIx(CIx code
) { return (uint)tabIx; }
1239 /**************************************************************************/
1240 public class TypeSpec
: MetaDataElement
{
1243 internal TypeSpec(Type aType
, MetaData md
)
1245 MemoryStream sig
= new MemoryStream();
1247 sigIx
= md
.AddToBlobHeap(sig
.ToArray());
1248 tabIx
= MDTable
.TypeSpec
;
1251 internal sealed override uint GetCodedIx(CIx code
)
1254 case (CIx
.TypeDefOrRef
) : return 2;
1255 case (CIx
.HasCustomAttr
) : return 13;
1256 case (CIx
.MemberRefParent
) : return 4;
1261 internal override uint Size(MetaData md
)
1263 return md
.BlobIndexSize();
1266 internal sealed override void Write(FileImage output
)
1268 //Console.WriteLine("Writing the blob index for a TypeSpec");
1269 output
.BlobIndex(sigIx
);
1274 /**************************************************************************/
1276 /// Base class for all IL types
1278 public abstract class Type
: MetaDataElement
{
1279 protected byte typeIndex
;
1280 protected TypeSpec typeSpec
;
1282 internal Type(byte tyIx
) { typeIndex = tyIx; }
1284 internal byte GetTypeIndex() { return typeIndex; }
1285 internal void SetTypeIndex (byte b
) { typeIndex = b; }
1287 internal virtual MetaDataElement
GetTypeSpec(MetaData md
)
1289 if (typeSpec
== null) {
1290 typeSpec
= new TypeSpec(this,md
);
1291 md
.AddToTable(MDTable
.TypeSpec
,typeSpec
);
1296 internal virtual void TypeSig(MemoryStream str
)
1298 throw(new TypeSignatureException(this.GetType().AssemblyQualifiedName
+
1299 " doesn't have a type signature!!"));
1303 public class ClassRefInst
: Type
{
1306 private bool is_value
;
1308 public ClassRefInst (Type type
, bool is_value
) : base (PrimitiveType
.Class
.GetTypeIndex ())
1311 this.is_value
= is_value
;
1313 typeIndex
= PrimitiveType
.ValueType
.GetTypeIndex ();
1314 tabIx
= MDTable
.TypeSpec
;
1317 internal sealed override void TypeSig(MemoryStream str
)
1323 /**************************************************************************/
1325 /// The base descriptor for a class
1327 public abstract class Class
: Type
{
1329 protected int row
= 0;
1330 public string name
, nameSpace
;
1331 protected uint nameIx
, nameSpaceIx
;
1332 protected MetaData _metaData
;
1333 internal Class(string nameSpaceName
, string className
, MetaData md
)
1334 : base(PrimitiveType
.Class
.GetTypeIndex ())
1336 nameSpace
= nameSpaceName
;
1338 nameIx
= md
.AddToStringsHeap(name
);
1339 nameSpaceIx
= md
.AddToStringsHeap(nameSpace
);
1343 internal Class(uint nsIx
, uint nIx
) : base(PrimitiveType
.Class
.GetTypeIndex ())
1349 internal Class (byte typeIndex
) : base (typeIndex
)
1351 nameSpace
= "Should not be used";
1352 name
= "Should not be used";
1355 internal virtual uint TypeDefOrRefToken() { return 0; }
1357 internal virtual void MakeValueClass(ValueClass vClass
)
1359 typeIndex
= PrimitiveType
.ValueType
.GetTypeIndex ();
1362 internal virtual string TypeName()
1364 return (nameSpace
+ "." + name
);
1367 internal override MetaDataElement
GetTypeSpec(MetaData md
)
1373 /**************************************************************************/
1374 // This Class produces entries in the TypeDef table of the MetaData
1375 // in the PE meta data.
1377 // NOTE: Entry 0 in TypeDef table is always the pseudo class <module>
1378 // which is the parent for functions and variables declared a module level
1381 /// The descriptor for a class defined in the IL (.class) in the current assembly/module
1384 public class ClassDef
: Class
{
1386 private static readonly byte ElementType_Class
= 0x12;
1389 ArrayList fields
= new ArrayList();
1390 ArrayList methods
= new ArrayList();
1392 ArrayList properties
;
1393 bool typeIndexChecked
= true;
1394 uint fieldIx
= 0, methodIx
= 0;
1395 byte[] securityActions
;
1398 ClassDef parentClass
;
1401 internal ClassDef(TypeAttr attrSet
, string nsName
, string name
,
1402 MetaData md
) : base(nsName
, name
, md
)
1405 if (! ((nsName
== "" && name
== "<Module>") || (nsName
== "System" && name
== "Object")) ) {
1406 superType
= metaData
.mscorlib
.GetSpecialSystemClass(PrimitiveType
.Object
);
1408 flags
= (uint)attrSet
;
1409 tabIx
= MDTable
.TypeDef
;
1412 internal void SetSuper(Class sClass
)
1415 if (! (sClass
is GenericTypeInst
))
1416 typeIndexChecked
= false;
1419 internal override void MakeValueClass(ValueClass vClass
)
1421 if (vClass
== ValueClass
.Enum
)
1422 superType
= metaData
.mscorlib
.EnumType();
1424 superType
= metaData
.mscorlib
.ValueType();
1426 typeIndex
= PrimitiveType
.ValueType
.GetTypeIndex ();
1429 public void SpecialNoSuper()
1435 /// Add an attribute to this class
1437 /// <param name="ta">the attribute to be added</param>
1438 public void AddAttribute(TypeAttr ta
)
1444 /// Add an interface that is implemented by this class
1446 /// <param name="iFace">the interface that is implemented</param>
1447 public void AddImplementedInterface(Class iFace
)
1449 metaData
.AddToTable(MDTable
.InterfaceImpl
,new InterfaceImpl(this,iFace
));
1453 /// Add a named generic type parameter
1455 public GenericParameter
AddGenericParameter (short index
, string name
)
1457 GenericParameter gp
= new GenericParameter (this, metaData
, index
, name
);
1458 metaData
.AddToTable (MDTable
.GenericParam
, gp
);
1463 /// Add a field to this class
1465 /// <param name="name">field name</param>
1466 /// <param name="fType">field type</param>
1467 /// <returns>a descriptor for this new field</returns>
1468 public FieldDef
AddField(string name
, Type fType
)
1470 FieldDef field
= new FieldDef(name
,fType
);
1476 /// Add a field to this class
1478 /// <param name="fAtts">attributes for this field</param>
1479 /// <param name="name">field name</param>
1480 /// <param name="fType">field type</param>
1481 /// <returns>a descriptor for this new field</returns>
1482 public FieldDef
AddField(FieldAttr fAtts
, string name
, Type fType
)
1484 FieldDef field
= new FieldDef(fAtts
,name
,fType
);
1489 public void SetFieldOrder (ArrayList fields
)
1491 this.fields
= fields
;
1495 /// Add a method to this class
1497 /// <param name="name">method name</param>
1498 /// <param name="retType">return type</param>
1499 /// <param name="pars">parameters</param>
1500 /// <returns>a descriptor for this new method</returns>
1501 public MethodDef
AddMethod(string name
, Type retType
, Param
[] pars
)
1503 // Console.WriteLine("Adding method " + name + " to class " + this.name);
1504 MethodDef meth
= new MethodDef(metaData
,name
,retType
, pars
);
1510 /// Add a method to this class
1512 /// <param name="mAtts">attributes for this method</param>
1513 /// <param name="iAtts">implementation attributes for this method</param>
1514 /// <param name="name">method name</param>
1515 /// <param name="retType">return type</param>
1516 /// <param name="pars">parameters</param>
1517 /// <returns>a descriptor for this new method</returns>
1518 public MethodDef
AddMethod(MethAttr mAtts
, ImplAttr iAtts
, string name
,
1519 Type retType
, Param
[] pars
) {
1520 // Console.WriteLine("Adding method " + name + " to class " + this.name);
1521 MethodDef meth
= new MethodDef(metaData
,mAtts
,iAtts
,name
,retType
,pars
);
1527 /// Add an event to this class
1529 /// <param name="name">event name</param>
1530 /// <param name="eType">event type</param>
1531 /// <returns>a descriptor for this new event</returns>
1532 public Event
AddEvent(string name
, Type eType
)
1534 Event e
= new Event(name
,eType
,this);
1535 if (events
== null) events
= new ArrayList();
1541 /// Add a property to this class
1543 /// <param name="name">property name</param>
1544 /// <param name="propType">property type</param>
1545 /// <returns>a descriptor for this new property</returns>
1546 public Property
AddProperty(string name
, Type retType
, Type
[] pars
)
1548 Property p
= new Property(name
, retType
, pars
, this);
1549 if (properties
== null) properties
= new ArrayList();
1555 /// Add a nested class to this class
1557 /// <param name="attrSet">attributes for this nested class</param>
1558 /// <param name="nsName">nested name space name</param>
1559 /// <param name="name">nested class name</param>
1560 /// <returns>a descriptor for this new nested class</returns>
1561 public ClassDef
AddNestedClass(TypeAttr attrSet
, string nsName
,
1563 ClassDef nClass
= new ClassDef(attrSet
,"",name
,metaData
);
1564 metaData
.AddToTable(MDTable
.TypeDef
,nClass
);
1565 metaData
.AddToTable(MDTable
.NestedClass
,new MapElem(nClass
,Row
,MDTable
.TypeDef
));
1566 nClass
.parentClass
= this;
1570 public static bool IsValueType (Class type
)
1572 return IsValueType (type
.nameSpace
, type
.name
);
1575 public static bool IsEnum (Class type
)
1577 return IsEnum (type
.nameSpace
, type
.name
);
1580 public static bool IsValueType (string nsName
, string name
)
1582 return (nsName
== "System" && name
== "ValueType");
1585 public static bool IsEnum (string nsName
, string name
)
1587 return (nsName
== "System" && name
== "Enum");
1591 /// Add a nested class to this class
1593 /// <param name="attrSet">attributes for this nested class</param>
1594 /// <param name="nsName">nested name space name</param>
1595 /// <param name="name">nested class name</param>
1596 /// <param name="sType">super type of this nested class</param>
1597 /// <returns>a descriptor for this new nested class</returns>
1598 public ClassDef
AddNestedClass(TypeAttr attrSet
, string nsName
,
1599 string name
, Class sType
) {
1600 ClassDef nClass
= AddNestedClass (attrSet
, nsName
, name
);
1601 nClass
.SetSuper(sType
);
1602 if (ClassDef
.IsValueType (sType
))
1603 nClass
.MakeValueClass (ValueClass
.ValueType
);
1605 if (ClassDef
.IsEnum (sType
))
1606 nClass
.MakeValueClass (ValueClass
.Enum
);
1608 if (ClassDef
.IsValueType (sType
) || ClassDef
.IsEnum (sType
))
1609 nClass
.SetTypeIndex (PrimitiveType
.ValueType
.GetTypeIndex ());
1611 nClass
.typeIndexChecked
= true;
1616 /// Add layout information for this class. This class must have the
1617 /// sequential or explicit attribute.
1619 /// <param name="packSize">packing size (.pack)</param>
1620 /// <param name="classSize">class size (.size)</param>
1621 public void AddLayoutInfo (int packSize
, int classSize
)
1623 layout
= new ClassLayout(packSize
,classSize
,this);
1627 /// Use a method as the implementation for another method (.override)
1629 /// <param name="decl">the method to be overridden</param>
1630 /// <param name="body">the implementation to be used</param>
1631 public void AddMethodOverride(Method decl
, Method body
)
1633 metaData
.AddToTable(MDTable
.MethodImpl
,new MethodImpl(this,decl
,body
));
1637 /// Add security to this class NOT YET IMPLEMENTED
1639 /// <param name="permissionSet"></param>
1640 public void AddSecurity(byte[] permissionSet
)
1642 throw(new NotYetImplementedException("Class security "));
1643 //flags |= HasSecurity;
1644 // securityActions = permissionSet;
1647 //public void AddLineInfo(int row, int col) { }
1649 internal void CheckTypeIndex()
1651 if (typeIndexChecked
) return;
1652 if (superType
is ClassDef
)
1653 ((ClassDef
)superType
).CheckTypeIndex();
1654 typeIndex
= superType
.GetTypeIndex();
1655 typeIndexChecked
= true;
1658 internal sealed override void BuildTables(MetaData md
)
1661 if ((flags
& (uint)TypeAttr
.Interface
) != 0) { superType = null; }
1662 // Console.WriteLine("Building tables for " + name);
1663 if (layout
!= null) md
.AddToTable(MDTable
.ClassLayout
,layout
);
1664 // Console.WriteLine("adding methods " + methods.Count);
1665 methodIx
= md
.TableIndex(MDTable
.Method
);
1666 for (int i
=0; i
< methods
.Count
; i
++) {
1667 md
.AddToTable(MDTable
.Method
,(MetaDataElement
)methods
[i
]);
1668 ((MethodDef
)methods
[i
]).BuildTables(md
);
1670 // Console.WriteLine("adding fields");
1671 fieldIx
= md
.TableIndex(MDTable
.Field
);
1672 for (int i
=0; i
< fields
.Count
; i
++) {
1673 md
.AddToTable(MDTable
.Field
,(MetaDataElement
)fields
[i
]);
1674 ((FieldDef
)fields
[i
]).BuildTables(md
);
1676 // Console.WriteLine("adding events and properties");
1677 if (events
!= null) {
1678 for (int i
=0; i
< events
.Count
; i
++) {
1679 md
.AddToTable(MDTable
.Event
,(Event
)events
[i
]);
1680 ((Event
)events
[i
]).BuildTables(md
);
1682 md
.AddToTable(MDTable
.EventMap
,
1683 new MapElem(this,((Event
)events
[0]).Row
,MDTable
.Event
));
1685 if (properties
!= null) {
1686 for (int i
=0; i
< properties
.Count
; i
++) {
1687 md
.AddToTable(MDTable
.Property
,(Property
)properties
[i
]);
1688 ((Property
)properties
[i
]).BuildTables(md
);
1690 md
.AddToTable(MDTable
.PropertyMap
,new MapElem(this,
1691 ((Property
)properties
[0]).Row
,MDTable
.Property
));
1693 // Console.WriteLine("End of building tables");
1697 internal sealed override uint Size(MetaData md
)
1699 return 4 + 2 * md
.StringsIndexSize() +
1700 md
.CodedIndexSize(CIx
.TypeDefOrRef
) +
1701 md
.TableIndexSize(MDTable
.Field
) +
1702 md
.TableIndexSize(MDTable
.Method
);
1705 internal sealed override void Write(FileImage output
)
1707 output
.Write(flags
);
1708 output
.StringsIndex(nameIx
);
1709 output
.StringsIndex(nameSpaceIx
);
1710 //if (superType != null)
1711 // Console.WriteLine("getting coded index for superType of " + name + " = " + superType.GetCodedIx(CIx.TypeDefOrRef));
1712 output
.WriteCodedIndex(CIx
.TypeDefOrRef
,superType
);
1713 output
.WriteIndex(MDTable
.Field
,fieldIx
);
1714 output
.WriteIndex(MDTable
.Method
,methodIx
);
1717 internal sealed override uint TypeDefOrRefToken()
1724 internal sealed override void TypeSig(MemoryStream sig
)
1726 if (!typeIndexChecked
) CheckTypeIndex();
1727 sig
.WriteByte(GetTypeIndex());
1728 MetaData
.CompressNum(TypeDefOrRefToken(),sig
);
1731 internal sealed override uint GetCodedIx(CIx code
)
1734 case (CIx
.TypeDefOrRef
) : return 0;
1735 case (CIx
.HasCustomAttr
) : return 3;
1736 case (CIx
.HasDeclSecurity
) : return 0;
1737 case (CIx
.TypeOrMethodDef
) : return 0;
1744 /**************************************************************************/
1746 /// Descriptor for a class/interface declared in another module of THIS
1747 /// assembly, or in another assembly.
1749 public class ClassRef
: Class
, IExternRef
, IResolutionScope
{
1751 protected IResolutionScope parent
;
1752 ExternClass externClass
;
1753 protected MetaData metaData
;
1755 internal ClassRef(string nsName
, string name
, MetaData md
) : base(nsName
, name
, md
)
1758 tabIx
= MDTable
.TypeRef
;
1762 /// Add a method to this class
1764 /// <param name="name">method name</param>
1765 /// <param name="retType">return type</param>
1766 /// <param name="pars">parameter types</param>
1767 /// <returns>a descriptor for this method</returns>
1768 public MethodRef
AddMethod(string name
, Type retType
, Type
[] pars
)
1770 return AddMethod (name
, retType
, pars
, 0);
1774 /// Add a method to this class
1776 /// <param name="name">method name</param>
1777 /// <param name="retType">return type</param>
1778 /// <param name="pars">parameter types</param>
1779 /// <param name="gen_param_count">num of generic parameters</param>
1780 /// <returns>a descriptor for this method</returns>
1781 public MethodRef
AddMethod (string name
, Type retType
, Type
[] pars
, int gen_param_count
)
1783 MethodRef meth
= new MethodRef (this, name
, retType
, pars
, false, null, gen_param_count
);
1784 metaData
.AddToTable(MDTable
.MemberRef
,meth
);
1789 /// Add a method to this class
1791 /// <param name="name">method name</param>
1792 /// <param name="retType">return type</param>
1793 /// <param name="pars">parameter types</param>
1794 /// <returns>a descriptor for this method</returns>
1795 public MethodRef
AddVarArgMethod(string name
, Type retType
,
1796 Type
[] pars
, Type
[] optPars
)
1798 MethodRef meth
= new MethodRef(this,name
,retType
,pars
,true,optPars
, 0);
1799 metaData
.AddToTable(MDTable
.MemberRef
,meth
);
1804 /// Add a field to this class
1806 /// <param name="name">field name</param>
1807 /// <param name="fType">field type</param>
1808 /// <returns>a descriptor for this field</returns>
1809 public FieldRef
AddField(string name
, Type fType
)
1811 FieldRef field
= new FieldRef(this,name
,fType
);
1812 metaData
.AddToTable(MDTable
.MemberRef
,field
);
1816 public ClassRef
AddClass (string nsName
, string name
)
1818 ClassRef aClass
= new ClassRef(nsName
,name
,metaData
);
1819 metaData
.AddToTable(MDTable
.TypeRef
,aClass
);
1820 aClass
.SetParent(this);
1824 public ClassRef
AddValueClass (string nsName
, string name
)
1826 ClassRef aClass
= AddClass (nsName
, name
);
1827 aClass
.MakeValueClass (ValueClass
.ValueType
);
1831 internal void SetParent(IResolutionScope par
)
1836 internal override string TypeName()
1838 if ((parent
!= null) && (parent
is AssemblyRef
))
1839 return (nameSpace
+ "." + name
+ ", " + ((AssemblyRef
)parent
).TypeName());
1841 return (nameSpace
+ name
);
1844 internal sealed override uint Size(MetaData md
)
1846 return md
.CodedIndexSize(CIx
.ResolutionScope
) + 2 *
1847 md
.StringsIndexSize();
1850 internal sealed override void Write(FileImage output
)
1852 output
.WriteCodedIndex(CIx
.ResolutionScope
,(MetaDataElement
) parent
);
1853 output
.StringsIndex(nameIx
);
1854 output
.StringsIndex(nameSpaceIx
);
1857 internal override sealed uint TypeDefOrRefToken()
1860 cIx
= (cIx
<< 2) | 0x1;
1864 internal override void TypeSig(MemoryStream sig
)
1866 sig
.WriteByte(GetTypeIndex());
1867 MetaData
.CompressNum(TypeDefOrRefToken(),sig
);
1870 internal sealed override uint GetCodedIx(CIx code
)
1873 case (CIx
.TypeDefOrRef
) : return 1;
1874 case (CIx
.HasCustomAttr
) : return 2;
1875 case (CIx
.MemberRefParent
) : return 1;
1876 case (CIx
.ResolutionScope
) : return 3;
1883 /**************************************************************************/
1884 public class ExternClassRef
: ClassRef
{
1886 ExternClass externClass
;
1888 internal ExternClassRef(TypeAttr attrs
, string nsName
, string name
,
1889 FileRef declFile
, MetaData md
) : base(nsName
,name
,md
)
1891 externClass
= new ExternClass(attrs
,nameSpaceIx
,nameIx
,declFile
);
1892 metaData
.AddToTable(MDTable
.ExportedType
,externClass
);
1895 internal ExternClassRef(string name
, MetaData md
) : base(null,name
,md
)
1899 public ClassRef
AddNestedClass(TypeAttr attrs
, string name
)
1901 ExternClassRef nestedClass
= new ExternClassRef(name
,metaData
);
1902 externClass
= new ExternClass(attrs
,0,nameIx
,this.externClass
);
1903 metaData
.AddToTable(MDTable
.ExportedType
,externClass
);
1909 /**************************************************************************/
1911 /// Descriptor for a class defined in another module of THIS assembly
1912 /// and exported (.class extern)
1915 internal class ExternClass
: Class
{
1917 MetaDataElement parent
;
1920 internal ExternClass(TypeAttr attr
, uint nsIx
, uint nIx
,
1921 MetaDataElement paren
) : base(nsIx
,nIx
)
1925 tabIx
= MDTable
.ExportedType
;
1928 internal sealed override uint Size(MetaData md
)
1930 return 8 + 2* md
.StringsIndexSize() + md
.CodedIndexSize(CIx
.Implementation
);
1933 internal sealed override void Write(FileImage output
)
1935 output
.Write(flags
);
1937 output
.StringsIndex(nameIx
);
1938 output
.StringsIndex(nameSpaceIx
);
1939 output
.WriteCodedIndex(CIx
.Implementation
,parent
);
1942 internal sealed override uint GetCodedIx(CIx code
)
1945 case (CIx
.HasCustomAttr
) : return 17;
1946 case (CIx
.Implementation
) : return 2;
1953 public class GenParam
: Type
{
1956 private string name
;
1958 public GenParam (int index
, string name
, GenParamType ptype
) : base ((byte) ptype
)
1962 tabIx
= MDTable
.TypeSpec
;
1966 get { return index; }
1967 set { index = value; }
1970 public string Name
{
1971 get { return name; }
1972 set { name = value; }
1975 public GenParamType Type
{
1976 get { return (GenParamType) GetTypeIndex (); }
1978 internal sealed override void TypeSig(MemoryStream str
)
1981 throw new Exception (String
.Format ("Unresolved {0} - {1}", (GenParamType
) GetTypeIndex (), name
));
1982 str
.WriteByte(typeIndex
);
1983 MetaData
.CompressNum ((uint) index
, str
);
1987 public class GenericTypeInst
: Class
{
1989 private Type gen_type
;
1990 private Type
[] gen_param
;
1992 bool inTable
= false;
1995 public GenericTypeInst (Type gen_type
, Type
[] gen_param
)
1996 : base ((byte) PrimitiveType
.GenericInst
.GetTypeIndex ())
1998 this.gen_type
= gen_type
;
1999 this.gen_param
= gen_param
;
2000 tabIx
= MDTable
.TypeSpec
;
2003 internal override MetaDataElement
GetTypeSpec (MetaData md
)
2006 md
.AddToTable (MDTable
.TypeSpec
, this);
2013 internal sealed override void TypeSig(MemoryStream str
)
2015 str
.WriteByte(typeIndex
);
2016 gen_type
.TypeSig (str
);
2017 MetaData
.CompressNum ((uint) gen_param
.Length
, str
);
2018 foreach (Type param
in gen_param
)
2019 param
.TypeSig (str
);
2022 internal sealed override void BuildTables (MetaData md
)
2026 MemoryStream str
= new MemoryStream ();
2028 sigIx
= md
.AddToBlobHeap (str
.ToArray ());
2033 internal sealed override uint Size (MetaData md
)
2035 return md
.BlobIndexSize ();
2038 internal sealed override void Write (FileImage output
)
2040 output
.BlobIndex (sigIx
);
2043 internal sealed override uint GetCodedIx (CIx code
)
2046 case (CIx
.TypeDefOrRef
): return 2;
2047 case (CIx
.MemberRefParent
): return 4;
2048 case (CIx
.HasCustomAttr
): return 13;
2054 public class GenericMethodSig
{
2056 private Type
[] gen_param
;
2058 public GenericMethodSig (Type
[] gen_param
)
2060 this.gen_param
= gen_param
;
2063 internal void TypeSig (MemoryStream str
)
2065 str
.WriteByte (0x0A); /* GENERIC_INST */
2066 MetaData
.CompressNum ((uint) gen_param
.Length
, str
);
2067 foreach (Type param
in gen_param
)
2068 param
.TypeSig (str
);
2071 internal uint GetSigIx (MetaData md
)
2073 MemoryStream sig
= new MemoryStream();
2075 return md
.AddToBlobHeap (sig
.ToArray());
2079 public class Sentinel
: Type
{
2081 public Sentinel () : base (0x41) { }
2083 internal sealed override void TypeSig(MemoryStream str
)
2085 str
.WriteByte(typeIndex
);
2089 /**************************************************************************/
2091 /// Descriptor for a FunctionPointer type
2094 public class MethPtrType
: Type
{
2106 /// Create a new function pointer type
2108 /// <param name="meth">the function to be referenced</param>
2109 public MethPtrType (CallConv callconv
, Type retType
, Type
[] pars
,
2110 bool varArgMeth
, Type
[] optPars
) : base(0x1B)
2112 this.retType
= retType
;
2113 callConv
= callconv
;
2115 this.varArgMeth
= varArgMeth
;
2116 if (parList
!= null) numPars
= (uint)parList
.Length
;
2118 optParList
= optPars
;
2119 if (optParList
!= null) numOptPars
= (uint)optParList
.Length
;
2120 callConv
|= CallConv
.Vararg
;
2122 tabIx
= MDTable
.TypeSpec
;
2125 internal sealed override void TypeSig(MemoryStream sig
)
2127 sig
.WriteByte(typeIndex
);
2128 // Bootlegged from method ref
2129 sig
.WriteByte((byte)callConv
);
2130 MetaData
.CompressNum (numPars
+ numOptPars
, sig
);
2131 retType
.TypeSig (sig
);
2132 for (int i
=0; i
< numPars
; i
++) {
2133 parList
[i
].TypeSig (sig
);
2136 sig
.WriteByte (0x41); // Write the sentinel
2137 for (int i
=0; i
< numOptPars
; i
++) {
2138 optParList
[i
].TypeSig (sig
);
2143 internal sealed override void BuildTables(MetaData md
)
2146 MemoryStream sig
= new MemoryStream();
2148 sigIx
= md
.AddToBlobHeap(sig
.ToArray());
2152 internal sealed override uint Size(MetaData md
)
2154 return md
.BlobIndexSize();
2157 internal sealed override void Write(FileImage output
)
2159 output
.BlobIndex(sigIx
);
2162 internal sealed override uint GetCodedIx(CIx code
) { return 0x1B; }
2167 /* Classes for Arrays */
2170 /// The IL Array type
2172 public abstract class Array
: Type
{
2174 protected Type elemType
;
2175 protected MetaData metaData
;
2176 protected string cnameSpace
, cname
;
2178 internal Array(Type eType
, byte TypeId
) : base(TypeId
)
2181 tabIx
= MDTable
.TypeSpec
;
2186 /// Single dimensional array with zero lower bound
2188 public class ZeroBasedArray
: Array
{
2191 /// Create a new array - elementType[]
2193 /// <param name="elementType">the type of the array elements</param>
2194 public ZeroBasedArray(Type elementType
) : base (elementType
, PrimitiveType
.SZArray
.GetTypeIndex ()) { }
2196 internal sealed override void TypeSig(MemoryStream str
)
2198 str
.WriteByte(typeIndex
);
2199 elemType
.TypeSig(str
);
2205 /// Multi dimensional array with explicit bounds
2207 public class BoundArray
: Array
{
2213 /// Create a new multi dimensional array type
2214 /// eg. elemType[1..5,3..10,5,,] would be
2215 /// new BoundArray(elemType,5,[1,3,0],[5,10,4])
2217 /// <param name="elementType">the type of the elements</param>
2218 /// <param name="dimensions">the number of dimensions</param>
2219 /// <param name="loBounds">lower bounds of dimensions</param>
2220 /// <param name="upBounds">upper bounds of dimensions</param>
2221 public BoundArray(Type elementType
, uint dimensions
, int[] loBounds
,
2222 int[] upBounds
) : base (elementType
,0x14)
2224 numDims
= dimensions
;
2225 lowerBounds
= loBounds
;
2226 if (upBounds
== null)
2228 sizes
= new int[loBounds
.Length
];
2229 for (int i
=0; i
< loBounds
.Length
; i
++) {
2230 sizes
[i
] = upBounds
[i
] - loBounds
[i
] + 1;
2235 /// Create a new multi dimensional array type
2236 /// eg. elemType[5,10,20] would be new BoundArray(elemType,3,[5,10,20])
2238 /// <param name="elementType">the type of the elements</param>
2239 /// <param name="dimensions">the number of dimensions</param>
2240 /// <param name="size">the sizes of the dimensions</param>
2241 public BoundArray(Type elementType
, uint dimensions
, int[] size
)
2242 : base (elementType
,0x14)
2244 numDims
= dimensions
;
2249 /// Create a new multi dimensional array type
2250 /// eg. elemType[,,] would be new BoundArray(elemType,3)
2252 /// <param name="elementType">the type of the elements</param>
2253 /// <param name="dimensions">the number of dimensions</param>
2254 public BoundArray(Type elementType
, uint dimensions
)
2255 : base (elementType
,0x14)
2257 numDims
= dimensions
;
2260 internal sealed override void TypeSig(MemoryStream str
)
2262 str
.WriteByte(typeIndex
);
2263 elemType
.TypeSig(str
);
2264 MetaData
.CompressNum(numDims
,str
);
2265 if ((sizes
!= null) && (sizes
.Length
> 0)) {
2267 MetaData
.CompressNum((uint)sizes
.Length
,str
);
2268 for (int i
=0; i
< sizes
.Length
; i
++) {
2269 MetaData
.CompressNum((uint)sizes
[i
],str
);
2271 } else str
.WriteByte(0);
2272 if ((lowerBounds
!= null) && (lowerBounds
.Length
> 0)) {
2273 MetaData
.CompressNum((uint)lowerBounds
.Length
,str
);
2274 for (int i
=0; i
< lowerBounds
.Length
; i
++) {
2275 MetaData
.CompressNum((uint)lowerBounds
[i
],str
);
2277 } else str
.WriteByte(0);
2285 /* Empty interface for grouping TypeRef's possible ResolutionScope
2286 namely : Module, ModuleRef, AssemblyRef and TypeRef */
2287 public interface IResolutionScope
{
2290 /**************************************************************************/
2292 /// Base class for scopes (extended by Module, ModuleRef, Assembly, AssemblyRef)
2294 public abstract class ResolutionScope
: MetaDataElement
, IResolutionScope
{
2296 protected uint nameIx
= 0;
2297 protected MetaData metaData
;
2298 protected string name
;
2300 internal ResolutionScope(string name
, MetaData md
)
2304 nameIx
= md
.AddToStringsHeap(name
);
2307 internal string GetName() { return name; }
2311 /**************************************************************************/
2313 /// Descriptor for THIS assembly (.assembly)
2315 public class Assembly
: ResolutionScope
{
2317 ushort majorVer
, minorVer
, buildNo
, revisionNo
;
2320 uint keyIx
= 0, cultIx
= 0;
2321 bool hasPublicKey
= false;
2323 internal Assembly(string name
, MetaData md
) : base(name
,md
)
2325 tabIx
= MDTable
.Assembly
;
2329 /// Add details about THIS assembly
2331 /// <param name="majVer">Major Version</param>
2332 /// <param name="minVer">Minor Version</param>
2333 /// <param name="bldNo">Build Number</param>
2334 /// <param name="revNo">Revision Number</param>
2335 /// <param name="key">Hash Key</param>
2336 /// <param name="hash">Hash Algorithm</param>
2337 /// <param name="cult">Culture</param>
2338 public void AddAssemblyInfo(int majVer
, int minVer
, int bldNo
, int revNo
,
2339 byte[] key
, uint hash
, string cult
)
2341 majorVer
= (ushort)majVer
;
2342 minorVer
= (ushort)minVer
;
2343 buildNo
= (ushort)bldNo
;
2344 revisionNo
= (ushort)revNo
;
2346 hasPublicKey
= (key
!= null);
2347 keyIx
= metaData
.AddToBlobHeap(key
);
2348 cultIx
= metaData
.AddToStringsHeap(cult
);
2352 /// Add an attribute to THIS assembly
2354 /// <param name="aa">assembly attribute</param>
2355 public void AddAssemblyAttr(AssemAttr aa
)
2360 internal sealed override uint Size(MetaData md
)
2362 return 16 + md
.BlobIndexSize() + 2 * md
.StringsIndexSize();
2365 internal sealed override void Write(FileImage output
)
2367 // Console.WriteLine("Writing assembly element with nameIx of " + nameIx + " at file offset " + output.Seek(0,SeekOrigin.Current));
2368 output
.Write((uint)hashAlgId
);
2369 output
.Write(majorVer
);
2370 output
.Write(minorVer
);
2371 output
.Write(buildNo
);
2372 output
.Write(revisionNo
);
2373 output
.Write(flags
);
2374 output
.BlobIndex(keyIx
);
2375 output
.StringsIndex(nameIx
);
2376 output
.StringsIndex(cultIx
);
2379 internal sealed override uint GetCodedIx(CIx code
)
2382 case (CIx
.HasCustomAttr
) : return 14;
2383 case (CIx
.HasDeclSecurity
) : return 2;
2388 internal bool HasPublicKey
{
2389 get { return hasPublicKey; }
2393 /**************************************************************************/
2395 /// Descriptor for THIS module
2397 public class Module
: ResolutionScope
{
2402 internal Module(string name
, MetaData md
) : base(name
,md
)
2404 mvid
= Guid
.NewGuid();
2405 mvidIx
= md
.AddToGUIDHeap(mvid
);
2406 tabIx
= MDTable
.Module
;
2410 get { return mvid; }
2413 internal sealed override uint Size(MetaData md
)
2415 return 2 + md
.StringsIndexSize() + 3 * md
.GUIDIndexSize();
2418 internal sealed override void Write(FileImage output
)
2420 output
.Write((short)0);
2421 output
.StringsIndex(nameIx
);
2422 output
.GUIDIndex(mvidIx
);
2423 output
.GUIDIndex(0);
2424 output
.GUIDIndex(0);
2427 internal sealed override uint GetCodedIx(CIx code
)
2430 case (CIx
.HasCustomAttr
) : return 7;
2431 case (CIx
.ResolutionScope
) : return 0;
2436 /**************************************************************************/
2438 /// Descriptor for another module in THIS assembly
2440 public class ModuleRef
: ResolutionScope
, IExternRef
{
2442 internal ModuleRef(MetaData md
, string name
) : base(name
,md
)
2444 tabIx
= MDTable
.ModuleRef
;
2448 /// Add a class to this external module. This is a class declared in
2449 /// another module of THIS assembly.
2451 /// <param name="nsName">name space name</param>
2452 /// <param name="name">class name</param>
2453 /// <returns>a descriptor for this class in another module</returns>
2454 public ClassRef
AddClass(string nsName
, string name
)
2456 ClassRef aClass
= new ClassRef(nsName
,name
,metaData
);
2457 metaData
.AddToTable(MDTable
.TypeRef
,aClass
);
2458 aClass
.SetParent(this);
2463 /// Make a file descriptor to correspond to this module. The file
2464 /// descriptor will have the same name as the module descriptor
2466 /// <param name="hashBytes">the hash of the file</param>
2467 /// <param name="hasMetaData">the file contains metadata</param>
2468 /// <param name="entryPoint">the program entry point is in this file</param>
2469 /// <returns>a descriptor for the file which contains this module</returns>
2470 public FileRef
MakeFile(byte[] hashBytes
, bool hasMetaData
, bool entryPoint
)
2472 FileRef file
= new FileRef(nameIx
,hashBytes
,hasMetaData
,entryPoint
,metaData
);
2473 metaData
.AddToTable(MDTable
.File
,file
);
2478 /// Add a value class to this module. This is a class declared in
2479 /// another module of THIS assembly.
2481 /// <param name="nsName">name space name</param>
2482 /// <param name="name">class name</param>
2483 /// <returns></returns>
2484 public ClassRef
AddValueClass(string nsName
, string name
)
2486 ClassRef aClass
= new ClassRef(nsName
,name
,metaData
);
2487 metaData
.AddToTable(MDTable
.TypeRef
,aClass
);
2488 aClass
.SetParent(this);
2489 aClass
.MakeValueClass(ValueClass
.ValueType
);
2494 /// Add a class which is declared public in this external module of
2495 /// THIS assembly. This class will be exported from this assembly.
2496 /// The ilasm syntax for this is .extern class
2498 /// <param name="attrSet">attributes of the class to be exported</param>
2499 /// <param name="nsName">name space name</param>
2500 /// <param name="name">external class name</param>
2501 /// <param name="declFile">the file where the class is declared</param>
2502 /// <param name="isValueClass">is this class a value type?</param>
2503 /// <returns>a descriptor for this external class</returns>
2504 public ExternClassRef
AddExternClass(TypeAttr attrSet
, string nsName
,
2505 string name
, FileRef declFile
,
2506 bool isValueClass
) {
2507 ExternClassRef cRef
= new ExternClassRef(attrSet
,nsName
,name
,declFile
,metaData
);
2508 metaData
.AddToTable(MDTable
.TypeRef
,cRef
);
2509 cRef
.SetParent(this);
2510 if (isValueClass
) cRef
.MakeValueClass(ValueClass
.ValueType
);
2515 /// Add a "global" method in another module
2517 /// <param name="name">method name</param>
2518 /// <param name="retType">return type</param>
2519 /// <param name="pars">method parameter types</param>
2520 /// <returns>a descriptor for this method in anther module</returns>
2521 public MethodRef
AddMethod(string name
, Type retType
, Type
[] pars
)
2523 MethodRef meth
= new MethodRef(this,name
,retType
,pars
,false,null, 0);
2524 metaData
.AddToTable(MDTable
.MemberRef
,meth
);
2529 /// Add a vararg method to this class
2531 /// <param name="name">method name</param>
2532 /// <param name="retType">return type</param>
2533 /// <param name="pars">parameter types</param>
2534 /// <param name="optPars">optional param types for this vararg method</param>
2535 /// <returns>a descriptor for this method</returns>
2536 public MethodRef
AddVarArgMethod(string name
, Type retType
,
2537 Type
[] pars
, Type
[] optPars
) {
2538 MethodRef meth
= new MethodRef(this,name
,retType
,pars
,true,optPars
, 0);
2539 metaData
.AddToTable(MDTable
.MemberRef
,meth
);
2544 /// Add a field in another module
2546 /// <param name="name">field name</param>
2547 /// <param name="fType">field type</param>
2548 /// <returns>a descriptor for this field in another module</returns>
2549 public FieldRef
AddField(string name
, Type fType
)
2551 FieldRef field
= new FieldRef(this,name
,fType
);
2552 metaData
.AddToTable(MDTable
.MemberRef
,field
);
2556 internal sealed override uint Size(MetaData md
)
2558 return md
.StringsIndexSize();
2561 internal sealed override void Write(FileImage output
)
2563 output
.StringsIndex(nameIx
);
2566 internal sealed override uint GetCodedIx(CIx code
)
2569 case (CIx
.HasCustomAttr
) : return 12;
2570 case (CIx
.MemberRefParent
) : return 2;
2571 case (CIx
.ResolutionScope
) : return 1;
2578 #region Classes for Constants
2580 /// Descriptor for a constant value
2582 public abstract class Constant
{
2583 protected uint size
= 0;
2584 protected Type type
;
2585 protected uint blobIndex
;
2586 protected bool addedToBlobHeap
= false;
2588 internal Constant() { }
2590 internal virtual uint GetBlobIndex(MetaData md
) { return 0; }
2592 internal uint GetSize() { return size; }
2594 internal byte GetTypeIndex() { return type.GetTypeIndex(); }
2596 internal virtual void Write(BinaryWriter bw
) { }
2600 /// Descriptor for a constant value
2602 public abstract class DataConstant
: Constant
{
2603 private uint dataOffset
= 0;
2605 internal DataConstant() { }
2607 public uint DataOffset
{
2608 get { return dataOffset; }
2609 set { dataOffset = value; }
2615 /// Boolean constant
2617 public class BoolConst
: Constant
{
2621 /// Create a new boolean constant with the value "val"
2623 /// <param name="val">value of this boolean constant</param>
2624 public BoolConst(bool val
)
2628 type
= PrimitiveType
.Boolean
;
2631 internal sealed override uint GetBlobIndex(MetaData md
)
2633 if (!addedToBlobHeap
) {
2634 if (val
) blobIndex
= md
.AddToBlobHeap((sbyte)1);
2635 else blobIndex
= md
.AddToBlobHeap((sbyte)0);
2636 addedToBlobHeap
= true;
2641 internal sealed override void Write(BinaryWriter bw
)
2643 if (val
) bw
.Write((sbyte)1);
2644 else bw
.Write((sbyte)0);
2649 public class ByteArrConst
: DataConstant
{
2652 public ByteArrConst(byte[] val
)
2654 type
= PrimitiveType
.String
;
2656 size
= (uint)val
.Length
;
2660 get { return type; }
2661 set { type = value; }
2664 internal sealed override uint GetBlobIndex(MetaData md
)
2666 if (!addedToBlobHeap
) {
2667 blobIndex
= md
.AddToBlobHeap(val
);
2668 addedToBlobHeap
= true;
2673 internal sealed override void Write(BinaryWriter bw
)
2680 public class CharConst
: Constant
{
2683 public CharConst(char val
)
2687 type
= PrimitiveType
.Char
;
2690 internal sealed override uint GetBlobIndex(MetaData md
)
2692 if (!addedToBlobHeap
) {
2693 blobIndex
= md
.AddToBlobHeap(val
);
2694 addedToBlobHeap
= true;
2699 internal sealed override void Write(BinaryWriter bw
)
2706 public class FloatConst
: DataConstant
{
2709 public FloatConst(float val
)
2713 type
= PrimitiveType
.Float32
;
2716 internal sealed override uint GetBlobIndex(MetaData md
)
2718 if (!addedToBlobHeap
) {
2719 blobIndex
= md
.AddToBlobHeap(val
);
2720 addedToBlobHeap
= true;
2725 internal sealed override void Write(BinaryWriter bw
)
2732 public class DoubleConst
: DataConstant
{
2735 public DoubleConst(double val
)
2739 type
= PrimitiveType
.Float64
;
2742 internal sealed override uint GetBlobIndex(MetaData md
)
2744 if (!addedToBlobHeap
) {
2745 blobIndex
= md
.AddToBlobHeap(val
);
2746 addedToBlobHeap
= true;
2751 internal sealed override void Write(BinaryWriter bw
)
2758 public class IntConst
: DataConstant
{
2761 public IntConst(sbyte val
)
2765 type
= PrimitiveType
.Int8
;
2768 public IntConst(short val
)
2772 type
= PrimitiveType
.Int16
;
2775 public IntConst(int val
)
2779 type
= PrimitiveType
.Int32
;
2782 public IntConst(long val
)
2786 type
= PrimitiveType
.Int64
;
2789 internal sealed override uint GetBlobIndex(MetaData md
)
2791 if (!addedToBlobHeap
) {
2793 case (1) : blobIndex
= md
.AddToBlobHeap((sbyte)val
); break;
2794 case (2) : blobIndex
= md
.AddToBlobHeap((short)val
); break;
2795 case (4) : blobIndex
= md
.AddToBlobHeap((int)val
); break;
2796 default : blobIndex
= md
.AddToBlobHeap(val
); break;
2798 addedToBlobHeap
= true;
2803 internal sealed override void Write(BinaryWriter bw
)
2806 case (1) : bw
.Write((sbyte)val
); break;
2807 case (2) : bw
.Write((short)val
); break;
2808 case (4) : bw
.Write((int)val
); break;
2809 default : bw
.Write(val
); break;
2815 public class UIntConst
: Constant
{
2818 public UIntConst(byte val
)
2822 type
= PrimitiveType
.UInt8
;
2824 public UIntConst(ushort val
)
2828 type
= PrimitiveType
.UInt16
;
2830 public UIntConst(uint val
)
2834 type
= PrimitiveType
.UInt32
;
2836 public UIntConst(ulong val
)
2840 type
= PrimitiveType
.UInt64
;
2843 internal sealed override uint GetBlobIndex(MetaData md
)
2845 if (!addedToBlobHeap
) {
2847 case (1) : blobIndex
= md
.AddToBlobHeap((byte)val
); break;
2848 case (2) : blobIndex
= md
.AddToBlobHeap((ushort)val
); break;
2849 case (4) : blobIndex
= md
.AddToBlobHeap((uint)val
); break;
2850 default : blobIndex
= md
.AddToBlobHeap(val
); break;
2852 addedToBlobHeap
= true;
2857 internal sealed override void Write(BinaryWriter bw
)
2860 case (1) : bw
.Write((byte)val
); break;
2861 case (2) : bw
.Write((ushort)val
); break;
2862 case (4) : bw
.Write((uint)val
); break;
2863 default : bw
.Write(val
); break;
2869 public class StringConst
: DataConstant
{
2872 public StringConst(string val
)
2875 size
= (uint)val
.Length
; // need to add null ??
2876 type
= PrimitiveType
.String
;
2879 internal sealed override uint GetBlobIndex(MetaData md
)
2881 if (!addedToBlobHeap
) {
2882 byte [] b
= Encoding
.Unicode
.GetBytes (val
);
2883 blobIndex
= md
.AddToBlobHeap(b
);
2884 addedToBlobHeap
= true;
2889 internal sealed override void Write(BinaryWriter bw
)
2896 public class NullConst
: Constant
{
2901 type
= PrimitiveType
.Class
;
2904 internal sealed override uint GetBlobIndex(MetaData md
)
2906 if (!addedToBlobHeap
) {
2907 blobIndex
= md
.AddToBlobHeap((int)0);
2908 addedToBlobHeap
= true;
2913 internal sealed override void Write(BinaryWriter bw
)
2920 public class AddressConstant
: DataConstant
{
2923 public AddressConstant(DataConstant dConst
)
2927 type
= PrimitiveType
.TypedRef
;
2930 internal sealed override void Write(BinaryWriter bw
)
2932 ((FileImage
)bw
).WriteDataRVA(data
.DataOffset
);
2937 public class RepeatedConstant
: DataConstant
{
2941 public RepeatedConstant(DataConstant dConst
, int repeatCount
)
2944 repCount
= (uint)repeatCount
;
2945 int[] sizes
= new int[1];
2946 sizes
[0] = repeatCount
;
2947 type
= new BoundArray(type
,1,sizes
);
2948 size
= data
.GetSize() * repCount
;
2951 internal sealed override void Write(BinaryWriter bw
)
2953 for (int i
=0; i
< repCount
; i
++) {
2960 public class ArrayConstant
: DataConstant
{
2961 DataConstant
[] dataVals
;
2963 public ArrayConstant(DataConstant
[] dVals
)
2966 for (int i
=0; i
< dataVals
.Length
; i
++) {
2967 size
+= dataVals
[i
].GetSize();
2971 internal sealed override void Write(BinaryWriter bw
)
2973 for (int i
=0; i
< dataVals
.Length
; i
++) {
2974 dataVals
[i
].Write(bw
);
2980 public class ClassType
: Constant
{
2984 public ClassType(string className
)
2987 type
= PrimitiveType
.ClassType
;
2990 public ClassType(Class classDesc
)
2993 type
= PrimitiveType
.ClassType
;
2996 internal override void Write(BinaryWriter bw
)
2998 if (name
== null) name
= desc
.TypeName();
3006 /**************************************************************************/
3008 /// Descriptor for a custom modifier of a type (modopt or modreq)
3011 public class CustomModifiedType
: Type
{
3017 /// Create a new custom modifier for a type
3019 /// <param name="type">the type to be modified</param>
3020 /// <param name="cmod">the modifier</param>
3021 /// <param name="cmodType">the type reference to be associated with the type</param>
3022 public CustomModifiedType(Type type
, CustomModifier cmod
, Class cmodType
)
3026 this.cmodType
= cmodType
;
3029 internal sealed override void TypeSig(MemoryStream str
)
3031 str
.WriteByte(typeIndex
);
3032 MetaData
.CompressNum(cmodType
.TypeDefOrRefToken(),str
);
3038 /**************************************************************************/
3040 /// Base class for Event and Property descriptors
3043 public class Feature
: MetaDataElement
{
3045 internal enum MethodType
: ushort { Setter
= 0x01, Getter
, Other
= 0x04, AddOn
= 0x08,
3046 RemoveOn
= 0x10, Fire
= 0x20 }
3048 private static readonly int INITSIZE
= 5;
3049 private static readonly ushort specialName
= 0x200;
3050 private static readonly ushort rtSpecialName
= 0x400;
3052 protected ClassDef parent
;
3053 protected ushort flags
= 0;
3054 protected string name
;
3055 protected int tide
= 0;
3056 protected uint nameIx
;
3057 protected MethodSemantics
[] methods
= new MethodSemantics
[INITSIZE
];
3059 internal Feature(string name
, ClassDef par
)
3065 internal void AddMethod(MethodDef meth
, MethodType mType
)
3067 if (tide
>= methods
.Length
) {
3068 int len
= methods
.Length
;
3069 MethodSemantics
[] mTmp
= methods
;
3070 methods
= new MethodSemantics
[len
* 2];
3071 for (int i
=0; i
< len
; i
++) {
3072 methods
[i
] = mTmp
[i
];
3075 methods
[tide
++] = new MethodSemantics(mType
,meth
,this);
3079 /// Set the specialName attribute for this Event or Property
3081 public void SetSpecialName()
3083 flags
|= specialName
;
3087 /// Set the RTSpecialName attribute for this Event or Property
3089 public void SetRTSpecialName()
3091 flags
|= rtSpecialName
;
3096 /**************************************************************************/
3098 /// Descriptor for an event
3100 public class Event
: Feature
{
3104 internal Event(string name
, Type eType
, ClassDef parent
)
3105 : base(name
, parent
)
3108 tabIx
= MDTable
.Event
;
3112 /// Add the addon method to this event
3114 /// <param name="addon">the addon method</param>
3115 public void AddAddon(MethodDef addon
)
3117 AddMethod(addon
,MethodType
.AddOn
);
3121 /// Add the removeon method to this event
3123 /// <param name="removeOn">the removeon method</param>
3124 public void AddRemoveOn(MethodDef removeOn
)
3126 AddMethod(removeOn
,MethodType
.RemoveOn
);
3130 /// Add the fire method to this event
3132 /// <param name="fire">the fire method</param>
3133 public void AddFire(MethodDef fire
)
3135 AddMethod(fire
,MethodType
.Fire
);
3139 /// Add another method to this event
3141 /// <param name="other">the method to be added</param>
3142 public void AddOther(MethodDef other
)
3144 AddMethod(other
,MethodType
.Other
);
3147 internal sealed override void BuildTables(MetaData md
)
3150 nameIx
= md
.AddToStringsHeap(name
);
3151 for (int i
=0; i
< tide
; i
++) {
3152 md
.AddToTable(MDTable
.MethodSemantics
,methods
[i
]);
3157 internal sealed override uint Size(MetaData md
)
3159 return 2 + md
.StringsIndexSize() + md
.CodedIndexSize(CIx
.TypeDefOrRef
);
3162 internal sealed override void Write(FileImage output
)
3164 output
.Write(flags
);
3165 output
.StringsIndex(nameIx
);
3166 output
.WriteCodedIndex(CIx
.TypeDefOrRef
,eventType
);
3169 internal sealed override uint GetCodedIx(CIx code
)
3172 case (CIx
.HasCustomAttr
) : return 10;
3173 case (CIx
.HasSemantics
) : return 0;
3180 /**************************************************************************/
3182 /// Descriptor for the Property of a class
3184 public class Property
: Feature
{
3186 private static readonly byte PropertyTag
= 0x8;
3187 private bool instance
;
3188 MethodDef getterMeth
;
3189 ConstantElem constVal
;
3190 uint typeBlobIx
= 0;
3195 internal Property(string name
, Type retType
, Type
[] pars
, ClassDef parent
) : base(name
, parent
)
3197 returnType
= retType
;
3199 if (pars
!= null) numPars
= (uint)pars
.Length
;
3200 tabIx
= MDTable
.Property
;
3204 /// Add a set method to this property
3206 /// <param name="setter">the set method</param>
3207 public void AddSetter(MethodDef setter
)
3209 AddMethod(setter
,MethodType
.Setter
);
3213 /// Add a get method to this property
3215 /// <param name="getter">the get method</param>
3216 public void AddGetter(MethodDef getter
)
3218 AddMethod(getter
,MethodType
.Getter
);
3219 getterMeth
= getter
;
3223 /// Add another method to this property
3225 /// <param name="other">the method</param>
3226 public void AddOther(MethodDef other
)
3228 AddMethod(other
,MethodType
.Other
);
3232 /// Add an initial value for this property
3234 /// <param name="constVal">the initial value for this property</param>
3235 public void AddInitValue(Constant constVal
)
3237 this.constVal
= new ConstantElem(this,constVal
);
3240 public void SetInstance (bool isInstance
)
3242 this.instance
= isInstance
;
3245 internal sealed override void BuildTables(MetaData md
)
3248 nameIx
= md
.AddToStringsHeap(name
);
3249 MemoryStream sig
= new MemoryStream();
3250 byte tag
= PropertyTag
;
3254 MetaData
.CompressNum(numPars
,sig
);
3255 returnType
.TypeSig(sig
);
3256 for (int i
=0; i
< numPars
; i
++) {
3257 parList
[i
].TypeSig(sig
);
3259 typeBlobIx
= md
.AddToBlobHeap(sig
.ToArray());
3260 for (int i
=0; i
< tide
; i
++) {
3261 md
.AddToTable(MDTable
.MethodSemantics
,methods
[i
]);
3263 if (constVal
!= null) {
3264 md
.AddToTable(MDTable
.Constant
,constVal
);
3265 constVal
.BuildTables(md
);
3270 internal sealed override uint Size(MetaData md
)
3272 return 2 + md
.StringsIndexSize() + md
.BlobIndexSize();
3275 internal sealed override void Write(FileImage output
)
3277 output
.Write(flags
);
3278 output
.StringsIndex(nameIx
);
3279 output
.BlobIndex(typeBlobIx
);
3282 internal sealed override uint GetCodedIx(CIx code
)
3285 case (CIx
.HasCustomAttr
) : return 9;
3286 case (CIx
.HasConst
) : return 2;
3287 case (CIx
.HasSemantics
) : return 1;
3294 /**************************************************************************/
3296 /// Base class for field/methods (member of a class)
3298 public abstract class Member
: MetaDataElement
{
3300 protected string name
;
3301 protected uint nameIx
= 0, sigIx
= 0;
3303 internal Member(string memName
)
3306 tabIx
= MDTable
.MemberRef
;
3311 /*****************************************************************************/
3313 /// Descriptor for a field of a class
3316 public abstract class Field
: Member
{
3318 protected static readonly byte FieldSig
= 0x6;
3320 protected Type type
;
3322 internal Field(string pfName
, Type pfType
) : base(pfName
)
3328 /**************************************************************************/
3330 /// Descriptor for a field defined in a class of THIS assembly/module
3332 public class FieldDef
: Field
{
3334 //private static readonly uint PInvokeImpl = 0x2000;
3335 private static readonly ushort HasFieldRVA
= 0x100;
3336 private static readonly ushort HasDefault
= 0x8000;
3339 ConstantElem constVal
;
3341 FieldMarshal marshalInfo
;
3344 internal FieldDef(string name
, Type fType
) : base(name
,fType
)
3346 tabIx
= MDTable
.Field
;
3349 internal FieldDef(FieldAttr attrSet
, string name
, Type fType
) : base(name
, fType
)
3351 flags
= (ushort)attrSet
;
3352 tabIx
= MDTable
.Field
;
3356 /// Add an attribute(s) to this field
3358 /// <param name="fa">the attribute(s) to be added</param>
3359 public void AddFieldAttr(FieldAttr fa
)
3361 flags
|= (ushort)fa
;
3365 /// Add a value for this field
3367 /// <param name="val">the value for the field</param>
3368 public void AddValue(Constant val
)
3370 constVal
= new ConstantElem(this,val
);
3371 flags
|= HasDefault
;
3375 /// Add an initial value for this field (at dataLabel) (.data)
3377 /// <param name="val">the value for the field</param>
3378 /// <param name="repeatVal">the number of repetitions of this value</param>
3379 public void AddDataValue(DataConstant val
)
3381 flags
|= HasFieldRVA
;
3382 rva
= new FieldRVA(this,val
);
3386 /// Set the offset of the field. Used for sequential or explicit classes.
3389 /// <param name="offs">field offset</param>
3390 public void SetOffset(uint offs
)
3392 layout
= new FieldLayout(this,offs
);
3396 /// Set the marshalling info for a field
3398 /// <param name="mInf"></param>
3399 public void SetMarshalInfo(NativeType marshallType
)
3401 flags
|= (ushort) FieldAttr
.HasFieldMarshal
;
3402 marshalInfo
= new FieldMarshal(this,marshallType
);
3405 internal sealed override void BuildTables(MetaData md
)
3408 nameIx
= md
.AddToStringsHeap(name
);
3409 MemoryStream sig
= new MemoryStream();
3410 sig
.WriteByte(FieldSig
);
3412 sigIx
= md
.AddToBlobHeap(sig
.ToArray());
3414 md
.AddToTable(MDTable
.FieldRVA
,rva
);
3415 rva
.BuildTables(md
);
3416 } else if (constVal
!= null) {
3417 md
.AddToTable(MDTable
.Constant
,constVal
);
3418 constVal
.BuildTables(md
);
3420 if (layout
!= null) md
.AddToTable(MDTable
.FieldLayout
,layout
);
3421 if (marshalInfo
!= null) {
3422 md
.AddToTable(MDTable
.FieldMarshal
,marshalInfo
);
3423 marshalInfo
.BuildTables(md
);
3428 internal sealed override uint Size(MetaData md
)
3430 return 2 + md
.StringsIndexSize() + md
.BlobIndexSize();
3433 internal sealed override void Write(FileImage output
)
3435 output
.Write(flags
);
3436 output
.StringsIndex(nameIx
);
3437 output
.BlobIndex(sigIx
);
3440 internal sealed override uint GetCodedIx(CIx code
)
3443 case (CIx
.HasConst
) : return 0;
3444 case (CIx
.HasCustomAttr
) : return 1;
3445 case (CIx
.HasFieldMarshal
) : return 0;
3446 case (CIx
.MemberForwarded
) : return 0;
3453 /**************************************************************************/
3455 /// Descriptor for a field of a class defined in another assembly/module
3457 public class FieldRef
: Field
{
3459 MetaDataElement parent
;
3461 internal FieldRef(MetaDataElement paren
, string name
, Type fType
) : base(name
, fType
)
3466 internal sealed override void BuildTables(MetaData md
)
3469 nameIx
= md
.AddToStringsHeap(name
);
3470 MemoryStream sig
= new MemoryStream();
3471 sig
.WriteByte(FieldSig
);
3473 sigIx
= md
.AddToBlobHeap(sig
.ToArray());
3477 internal sealed override uint Size(MetaData md
)
3479 return md
.CodedIndexSize(CIx
.MemberRefParent
) + md
.StringsIndexSize() + md
.BlobIndexSize();
3482 internal sealed override void Write(FileImage output
)
3484 output
.WriteCodedIndex(CIx
.MemberRefParent
,parent
);
3485 output
.StringsIndex(nameIx
);
3486 output
.BlobIndex(sigIx
);
3489 internal sealed override uint GetCodedIx(CIx code
) { return 6; }
3493 /**************************************************************************/
3495 /// Base class for Method Descriptors
3498 public abstract class Method
: Member
{
3500 internal Method (string methName
) : base (methName
)
3503 public abstract void AddCallConv(CallConv cconv
);
3504 internal abstract void TypeSig(MemoryStream sig
);
3505 internal abstract uint GetSigIx(MetaData md
);
3508 /**************************************************************************/
3510 /// Descriptor for a method defined in THIS assembly/module
3514 public class MethodDef
: Method
{
3516 private static readonly ushort PInvokeImpl
= 0x2000;
3517 //private static readonly uint UnmanagedExport = 0x0008;
3518 // private static readonly byte LocalSigByte = 0x7;
3519 uint parIx
= 0, textOffset
= 0;
3520 private CallConv callConv
= CallConv
.Default
;
3521 private Type retType
;
3522 private int gen_param_count
;
3525 CILInstructions code
;
3526 ArrayList securityActions
= new ArrayList();
3530 ushort methFlags
= 0, implFlags
= 0;
3531 int maxStack
= 0, numPars
= 0;
3532 bool entryPoint
= false;
3534 ArrayList varArgSigList
;
3535 ImplMap pinvokeImpl
;
3539 internal MethodDef(MetaData md
, string name
, Type retType
, Param
[] pars
) : base (name
)
3541 this.retType
= retType
;
3544 if (parList
!= null) numPars
= parList
.Length
;
3545 tabIx
= MDTable
.Method
;
3548 internal MethodDef (MetaData md
, MethAttr mAttrSet
, ImplAttr iAttrSet
, string name
,
3549 Type retType
, Param
[] pars
) : this (md
, name
, retType
, pars
)
3551 methFlags
= (ushort)mAttrSet
;
3552 implFlags
= (ushort)iAttrSet
;
3555 internal Param
[] GetPars()
3560 internal override uint GetSigIx(MetaData md
)
3562 MemoryStream sig
= new MemoryStream();
3564 return md
.AddToBlobHeap(sig
.ToArray());
3567 public override void AddCallConv(CallConv cconv
)
3573 /// Add some attributes to this method descriptor
3575 /// <param name="ma">the attributes to be added</param>
3576 public void AddMethAttribute(MethAttr ma
)
3578 methFlags
|= (ushort)ma
;
3582 /// Add some implementation attributes to this method descriptor
3584 /// <param name="ia">the attributes to be added</param>
3585 public void AddImplAttribute(ImplAttr ia
)
3587 implFlags
|= (ushort)ia
;
3590 public void AddPInvokeInfo(ModuleRef scope
, string methName
,
3591 PInvokeAttr callAttr
) {
3592 pinvokeImpl
= new ImplMap((ushort)callAttr
,this,methName
,scope
);
3593 methFlags
|= PInvokeImpl
;
3597 /// Add a named generic type parameter
3599 public GenericParameter
AddGenericParameter (short index
, string name
)
3601 GenericParameter gp
= new GenericParameter (this, metaData
, index
, name
);
3602 metaData
.AddToTable (MDTable
.GenericParam
, gp
);
3608 /// Set the maximum stack height for this method
3610 /// <param name="maxStack">the maximum height of the stack</param>
3611 public void SetMaxStack(int maxStack
)
3613 this.maxStack
= maxStack
;
3617 /// Add local variables to this method
3619 /// <param name="locals">the locals to be added</param>
3620 /// <param name="initLocals">are locals initialised to default values</param>
3621 public void AddLocals(Local
[] locals
, bool initLocals
)
3623 this.locals
= locals
;
3624 this.initLocals
= initLocals
;
3627 /* Add Marshal info for return type */
3628 public void AddRetTypeMarshallInfo (NativeType marshallType
)
3630 ret_param
= new Param (ParamAttr
.HasFieldMarshal
, "", retType
);
3631 ret_param
.AddMarshallInfo (marshallType
);
3635 /// Mark this method as having an entry point
3637 public void DeclareEntryPoint()
3643 /// Create a code buffer for this method to add the IL instructions to
3645 /// <returns>a buffer for this method's IL instructions</returns>
3646 public CILInstructions
CreateCodeBuffer()
3648 code
= new CILInstructions(metaData
);
3653 /// Make a method reference descriptor for this method to be used
3654 /// as a callsite signature for this vararg method
3656 /// <param name="optPars">the optional pars for the vararg method call</param>
3657 /// <returns></returns>
3658 public MethodRef
MakeVarArgSignature(Type
[] optPars
)
3660 Type
[] pars
= new Type
[numPars
];
3661 MethodRef varArgSig
;
3662 for (int i
=0; i
< numPars
; i
++) {
3663 pars
[i
] = parList
[i
].GetParType();
3665 varArgSig
= new MethodRef(this,name
,retType
,pars
,true,optPars
, 0);
3667 if (varArgSigList
== null)
3668 varArgSigList
= new ArrayList ();
3669 varArgSigList
.Add (varArgSig
);
3673 internal sealed override void TypeSig(MemoryStream sig
)
3675 sig
.WriteByte((byte)callConv
);
3676 if ((callConv
& CallConv
.Generic
) == CallConv
.Generic
)
3677 MetaData
.CompressNum ((uint) gen_param_count
, sig
);
3678 MetaData
.CompressNum((uint)numPars
,sig
);
3679 if (ret_param
!= null)
3680 ret_param
.seqNo
= 0;
3681 retType
.TypeSig(sig
);
3682 for (ushort i
=0; i
< numPars
; i
++) {
3683 parList
[i
].seqNo
= (ushort)(i
+1);
3684 parList
[i
].TypeSig(sig
);
3688 internal sealed override void BuildTables(MetaData md
)
3691 if (pinvokeImpl
!= null) {
3692 md
.AddToTable(MDTable
.ImplMap
,pinvokeImpl
);
3693 pinvokeImpl
.BuildTables(md
);
3695 if (entryPoint
) md
.SetEntryPoint(this);
3697 if (locals
!= null) {
3698 localSig
= new LocalSig(locals
);
3699 md
.AddToTable(MDTable
.StandAloneSig
,localSig
);
3700 localSig
.BuildTables(md
);
3701 locToken
= localSig
.Token();
3704 code
.CheckCode(locToken
,initLocals
,maxStack
);
3705 textOffset
= md
.AddCode(code
);
3707 nameIx
= md
.AddToStringsHeap(name
);
3708 sigIx
= GetSigIx(md
);
3709 parIx
= md
.TableIndex(MDTable
.Param
);
3710 if (ret_param
!= null) {
3711 md
.AddToTable(MDTable
.Param
, ret_param
);
3712 ret_param
.BuildTables(md
);
3714 for (int i
=0; i
< numPars
; i
++) {
3715 md
.AddToTable(MDTable
.Param
,parList
[i
]);
3716 parList
[i
].BuildTables(md
);
3718 if (varArgSigList
!= null) {
3719 foreach (MethodRef varArgSig
in varArgSigList
) {
3720 md
.AddToTable(MDTable
.MemberRef
,varArgSig
);
3721 varArgSig
.BuildTables(md
);
3724 // Console.WriteLine("method has " + numPars + " parameters");
3728 internal sealed override uint Size(MetaData md
)
3730 return 8 + md
.StringsIndexSize() + md
.BlobIndexSize() + md
.TableIndexSize(MDTable
.Param
);
3733 internal sealed override void Write(FileImage output
)
3735 if (ZeroRva ()) output
.Write(0);
3736 else output
.WriteCodeRVA(textOffset
);
3737 output
.Write(implFlags
);
3738 output
.Write(methFlags
);
3739 output
.StringsIndex(nameIx
);
3740 output
.BlobIndex(sigIx
);
3741 output
.WriteIndex(MDTable
.Param
,parIx
);
3744 internal bool ZeroRva ()
3746 return (((methFlags
& (ushort)MethAttr
.Abstract
) != 0) ||
3747 ((implFlags
& (ushort)ImplAttr
.Runtime
) != 0) ||
3748 ((implFlags
& (ushort)ImplAttr
.InternalCall
) != 0) ||
3749 (pinvokeImpl
!= null)); // TODO: Not entirely true but works for now
3752 internal sealed override uint GetCodedIx(CIx code
)
3755 case (CIx
.HasCustomAttr
) : return 0;
3756 case (CIx
.HasDeclSecurity
) : return 1;
3757 case (CIx
.MemberRefParent
) : return 3;
3758 case (CIx
.MethodDefOrRef
) : return 0;
3759 case (CIx
.MemberForwarded
) : return 1;
3760 case (CIx
.CustomAttributeType
) : return 2;
3761 case (CIx
.TypeOrMethodDef
) : return 1;
3767 /**************************************************************************/
3769 /// Descriptor for a method defined in another assembly/module
3771 public class MethodRef
: Method
{
3773 private static readonly byte Sentinel
= 0x41;
3774 Type
[] parList
, optParList
;
3775 MetaDataElement parent
;
3776 uint numPars
= 0, numOptPars
= 0;
3777 CallConv callConv
= CallConv
.Default
;
3779 int gen_param_count
;
3781 internal MethodRef(MetaDataElement paren
, string name
, Type retType
,
3782 Type
[] pars
, bool varArgMeth
, Type
[] optPars
, int gen_param_count
) : base(name
)
3786 this.retType
= retType
;
3787 if (parList
!= null) numPars
= (uint)parList
.Length
;
3789 optParList
= optPars
;
3790 if (optParList
!= null) numOptPars
= (uint)optParList
.Length
;
3791 callConv
= CallConv
.Vararg
;
3793 this.gen_param_count
= gen_param_count
;
3796 internal override uint GetSigIx(MetaData md
)
3798 MemoryStream sig
= new MemoryStream();
3800 return md
.AddToBlobHeap(sig
.ToArray());
3803 public override void AddCallConv(CallConv cconv
)
3808 internal sealed override void TypeSig(MemoryStream sig
)
3810 sig
.WriteByte((byte)callConv
);
3811 if ((callConv
& CallConv
.Generic
) == CallConv
.Generic
)
3812 MetaData
.CompressNum ((uint) gen_param_count
, sig
);
3813 MetaData
.CompressNum(numPars
+numOptPars
,sig
);
3814 retType
.TypeSig(sig
);
3815 for (int i
=0; i
< numPars
; i
++) {
3816 parList
[i
].TypeSig(sig
);
3818 if (numOptPars
> 0) {
3819 sig
.WriteByte(Sentinel
);
3820 for (int i
=0; i
< numOptPars
; i
++) {
3821 optParList
[i
].TypeSig(sig
);
3826 internal sealed override void BuildTables(MetaData md
)
3829 nameIx
= md
.AddToStringsHeap(name
);
3830 sigIx
= GetSigIx(md
);
3834 internal sealed override uint Size(MetaData md
)
3836 return md
.CodedIndexSize(CIx
.MemberRefParent
) + md
.StringsIndexSize() + md
.BlobIndexSize();
3839 internal sealed override void Write(FileImage output
)
3841 output
.WriteCodedIndex(CIx
.MemberRefParent
,parent
);
3842 output
.StringsIndex(nameIx
);
3843 output
.BlobIndex(sigIx
);
3846 internal sealed override uint GetCodedIx(CIx code
)
3849 case (CIx
.HasCustomAttr
) : return 6;
3850 case (CIx
.MethodDefOrRef
) : return 1;
3851 case (CIx
.CustomAttributeType
) : return 3;
3859 /**************************************************************************/
3861 /// Descriptors for native types used for marshalling
3863 public class NativeType
{
3864 public static readonly NativeType Void
= new NativeType(0x01);
3865 public static readonly NativeType Boolean
= new NativeType(0x02);
3866 public static readonly NativeType Int8
= new NativeType(0x03);
3867 public static readonly NativeType UInt8
= new NativeType(0x04);
3868 public static readonly NativeType Int16
= new NativeType(0x05);
3869 public static readonly NativeType UInt16
= new NativeType(0x06);
3870 public static readonly NativeType Int32
= new NativeType(0x07);
3871 public static readonly NativeType UInt32
= new NativeType(0x08);
3872 public static readonly NativeType Int64
= new NativeType(0x09);
3873 public static readonly NativeType UInt64
= new NativeType(0x0A);
3874 public static readonly NativeType Float32
= new NativeType(0x0B);
3875 public static readonly NativeType Float64
= new NativeType(0x0C);
3876 public static readonly NativeType Currency
= new NativeType(0x0F);
3877 public static readonly NativeType BStr
= new NativeType(0x13);
3878 public static readonly NativeType LPStr
= new NativeType(0x14);
3879 public static readonly NativeType LPWStr
= new NativeType(0x15);
3880 public static readonly NativeType LPTStr
= new NativeType(0x16);
3881 public static readonly NativeType FixedSysString
= new NativeType(0x17);
3882 public static readonly NativeType IUnknown
= new NativeType(0x19);
3883 public static readonly NativeType IDispatch
= new NativeType(0x1A);
3884 public static readonly NativeType Struct
= new NativeType(0x1B);
3885 public static readonly NativeType Interface
= new NativeType(0x1C);
3886 public static readonly NativeType Int
= new NativeType(0x1F);
3887 public static readonly NativeType UInt
= new NativeType(0x20);
3888 public static readonly NativeType ByValStr
= new NativeType(0x22);
3889 public static readonly NativeType AnsiBStr
= new NativeType(0x23);
3890 public static readonly NativeType TBstr
= new NativeType(0x24);
3891 public static readonly NativeType VariantBool
= new NativeType(0x25);
3892 public static readonly NativeType FuncPtr
= new NativeType(0x26);
3893 public static readonly NativeType AsAny
= new NativeType(0x28);
3895 protected byte typeIndex
;
3897 internal NativeType(byte tyIx
) { typeIndex = tyIx; }
3898 internal byte GetTypeIndex() { return typeIndex; }
3900 internal virtual byte[] ToBlob()
3902 byte[] bytes
= new byte[1];
3903 bytes
[0] = GetTypeIndex();
3909 public class FixedSysString
: NativeType
{
3913 public FixedSysString (uint size
) : base (NativeType
.FixedSysString
.GetTypeIndex ())
3918 internal override byte [] ToBlob ()
3920 MemoryStream str
= new MemoryStream ();
3921 str
.WriteByte (GetTypeIndex ());
3922 MetaData
.CompressNum (size
, str
);
3923 return str
.ToArray ();
3928 public class NativeArray
: NativeType
{
3930 NativeType elemType
;
3931 int numElem
= -1, parNum
= -1, elemMult
= -1;
3933 public NativeArray(NativeType elemType
) : this (elemType
, -1, -1, -1)
3935 this.elemType
= elemType
;
3938 /* public NativeArray(NativeType elemType, int len) : base(0x2A) {
3939 this.elemType = elemType;
3944 public NativeArray(NativeType elemType
, int numElem
, int parNumForLen
, int elemMult
) : base(0x2A)
3946 this.elemType
= elemType
;
3947 this.numElem
= numElem
;
3948 parNum
= parNumForLen
;
3949 this.elemMult
= elemMult
;
3952 public NativeArray(NativeType elemType
, int numElem
, int parNumForLen
)
3953 : this (elemType
, numElem
, parNumForLen
, -1)
3957 internal override byte[] ToBlob()
3959 MemoryStream str
= new MemoryStream();
3960 str
.WriteByte(GetTypeIndex());
3961 if (elemType
== null) str
.WriteByte(0x50); // no info (MAX)
3962 else str
.WriteByte(elemType
.GetTypeIndex());
3964 /* see : mono/metadata/metadata.c:mono_metadata_parse_marshal_spec
3965 * LAMESPEC: Older spec versions say elemMult comes before
3966 * len. Newer spec versions don't talk about elemMult at
3967 * all, but csc still emits it, and it is used to distinguish
3968 * between parNum being 0, and parNum being omitted.
3973 return str
.ToArray ();
3975 MetaData
.CompressNum((uint) parNum
,str
);
3976 if (numElem
!= -1) {
3977 MetaData
.CompressNum ((uint) numElem
, str
);
3979 // <native_type> [ int32 ]
3980 MetaData
.CompressNum((uint) elemMult
,str
);
3981 //else <native_type> [ int32 + int32 ]
3982 } else if (elemMult
!= -1) {
3983 // When can this occur ?
3984 MetaData
.CompressNum (0, str
);
3985 MetaData
.CompressNum((uint) elemMult
,str
);
3987 //else <native_type> [ + int32 ]
3989 return str
.ToArray();
3994 public class SafeArray
: NativeType
{
3996 SafeArrayType elemType
;
3999 public SafeArray() : base(0x1D)
4003 public SafeArray(SafeArrayType elemType
) : base(0x1D)
4005 this.elemType
= elemType
;
4009 internal override byte[] ToBlob()
4011 byte[] bytes
= new byte[hasElemType
? 2 : 1];
4012 bytes
[0] = GetTypeIndex();
4014 bytes
[1] = (byte)elemType
;
4020 public class FixedArray
: NativeType
{
4022 NativeType elemType
;
4025 //public FixedArray(NativeType elemType, int numElems) : base(0x1E) {
4026 public FixedArray(int numElems
) : base(0x1E)
4028 //this.elemType = elemType;
4029 numElem
= (uint)numElems
;
4032 internal override byte[] ToBlob()
4034 MemoryStream str
= new MemoryStream();
4035 str
.WriteByte(GetTypeIndex());
4036 MetaData
.CompressNum(numElem
,str
);
4038 fixed array [5] lpstr [2]
4039 This format is not supported by ilasm 1.1.4322.2032,
4040 but is supported by 2.0.5125..
4041 ilasm 1.1 only supports "fixed array [5]"
4042 if (elemType == null) str.WriteByte(0x50); // no info (MAX)
4043 else str.WriteByte(elemType.GetTypeIndex());*/
4045 return str
.ToArray();
4050 public class CustomMarshaller
: NativeType
{
4053 string marshallerName
;
4056 public CustomMarshaller(string typeNameOrGUID
, string marshallerName
,
4057 string optCookie
) : base(0x2C)
4059 typeName
= typeNameOrGUID
;
4060 this.marshallerName
= marshallerName
;
4064 public CustomMarshaller(string marshallerName
, string optCookie
)
4065 :this (null, marshallerName
, optCookie
)
4069 internal override byte[] ToBlob()
4071 MemoryStream str
= new MemoryStream();
4072 BinaryWriter bw
= new BinaryWriter(str
,new UTF8Encoding());
4073 bw
.Write(GetTypeIndex());
4074 //Native type name & unmanaged type - unused
4075 //See mono/metadata/metadata.c : mono_metadata_parse_marshal_spec
4076 bw
.Write ((byte) 0); // Native Type name, unused
4077 bw
.Write ((byte) 0); // Unmanaged type, unused
4078 if (marshallerName
!= null) {
4079 MetaData
.CompressNum ((uint)marshallerName
.Length
, str
);
4080 bw
.Write(marshallerName
.ToCharArray());
4082 bw
.Write ((byte) 0);
4084 if (cookie
!= null) {
4085 MetaData
.CompressNum ((uint)cookie
.Length
, str
);
4086 bw
.Write(cookie
.ToCharArray());
4088 bw
.Write ((byte) 0);
4091 return str
.ToArray();
4095 /**************************************************************************/
4097 /// Descriptor for the Primitive types defined in IL
4099 public class PrimitiveType
: Type
{
4101 private string name
;
4102 private int systemTypeIndex
;
4103 public static int NumSystemTypes
= 18;
4105 public static readonly PrimitiveType Void
= new PrimitiveType(0x01,"Void",0);
4106 public static readonly PrimitiveType Boolean
= new PrimitiveType(0x02,"Boolean",1);
4107 public static readonly PrimitiveType Char
= new PrimitiveType(0x03,"Char",2);
4108 public static readonly PrimitiveType Int8
= new PrimitiveType(0x04,"SByte",3);
4109 public static readonly PrimitiveType UInt8
= new PrimitiveType(0x05,"Byte",4);
4110 public static readonly PrimitiveType Int16
= new PrimitiveType(0x06,"Int16",5);
4111 public static readonly PrimitiveType UInt16
= new PrimitiveType(0x07,"UInt16",6);
4112 public static readonly PrimitiveType Int32
= new PrimitiveType(0x08,"Int32",7);
4113 public static readonly PrimitiveType UInt32
= new PrimitiveType(0x09,"UInt32",8);
4114 public static readonly PrimitiveType Int64
= new PrimitiveType(0x0A,"Int64",9);
4115 public static readonly PrimitiveType UInt64
= new PrimitiveType(0x0B,"UInt64",10);
4116 public static readonly PrimitiveType Float32
= new PrimitiveType(0x0C,"Single",11);
4117 public static readonly PrimitiveType Float64
= new PrimitiveType(0x0D,"Double",12);
4118 public static readonly PrimitiveType String
= new PrimitiveType(0x0E,"String",13);
4119 internal static readonly PrimitiveType Class
= new PrimitiveType(0x12);
4120 internal static readonly PrimitiveType Var
= new PrimitiveType(0x13);
4121 internal static readonly PrimitiveType GenericInst
= new PrimitiveType(0x15);
4122 public static readonly PrimitiveType TypedRef
= new PrimitiveType(0x16,"TypedReference",14);
4123 public static readonly PrimitiveType IntPtr
= new PrimitiveType(0x18,"IntPtr",15);
4124 public static readonly PrimitiveType UIntPtr
= new PrimitiveType(0x19,"UIntPtr",16);
4125 public static readonly PrimitiveType Object
= new PrimitiveType(0x1C,"Object",17);
4126 internal static readonly PrimitiveType ClassType
= new PrimitiveType(0x50);
4127 internal static readonly PrimitiveType SZArray
= new PrimitiveType(0x1D);
4128 internal static readonly PrimitiveType MVar
= new PrimitiveType(0x1E);
4129 internal static readonly PrimitiveType ValueType
= new PrimitiveType(0x11, "ValueType", 18);
4130 public static readonly PrimitiveType NativeInt
= IntPtr
;
4131 public static readonly PrimitiveType NativeUInt
= UIntPtr
;
4133 internal PrimitiveType(byte typeIx
) : base(typeIx
) { }
4135 internal PrimitiveType(byte typeIx
, string name
, int STIx
) : base(typeIx
)
4138 this.systemTypeIndex
= STIx
;
4141 internal string GetName() { return name; }
4143 internal int GetSystemTypeIx() { return systemTypeIndex; }
4145 internal sealed override void TypeSig(MemoryStream str
)
4147 str
.WriteByte(typeIndex
);
4150 internal override MetaDataElement
GetTypeSpec(MetaData md
)
4152 TypeSpec tS
= md
.GetPrimitiveTypeSpec(systemTypeIndex
);
4154 tS
= new TypeSpec(this,md
);
4155 md
.SetPrimitiveTypeSpec(systemTypeIndex
,tS
);
4156 md
.AddToTable(MDTable
.TypeSpec
,tS
);
4163 /**************************************************************************/
4165 /// Descriptor for an pointer (type * or type &)
4167 public abstract class PtrType
: Type
{
4171 internal PtrType(Type bType
, byte typeIx
) : base(typeIx
)
4174 tabIx
= MDTable
.TypeSpec
;
4177 internal sealed override void TypeSig(MemoryStream str
)
4179 str
.WriteByte(typeIndex
);
4180 baseType
.TypeSig(str
);
4184 /**************************************************************************/
4186 /// Descriptor for a managed pointer (type & or byref)
4189 public class ManagedPointer
: PtrType
{
4192 /// Create new managed pointer to baseType
4194 /// <param name="bType">the base type of the pointer</param>
4195 public ManagedPointer(Type baseType
) : base(baseType
,0x10) { }
4198 /**************************************************************************/
4200 /// Descriptor for an unmanaged pointer (type *)
4202 public class UnmanagedPointer
: PtrType
{
4205 /// Create a new unmanaged pointer to baseType
4207 /// <param name="baseType">the base type of the pointer</param>
4208 public UnmanagedPointer(Type baseType
) : base(baseType
, 0x0F) { }
4212 /**************************************************************************/
4214 public interface IExternRef
{
4215 ClassRef
AddClass(string nsName
, string name
);
4216 ClassRef
AddValueClass(string nsName
, string name
);
4220 /// A reference to an external assembly (.assembly extern)
4222 public class AssemblyRef
: ResolutionScope
, IExternRef
{
4224 private ushort major
, minor
, build
, revision
;
4225 uint flags
, keyIx
, hashIx
, cultIx
;
4226 bool hasVersion
= false, isKeyToken
= false;
4230 internal AssemblyRef(MetaData md
, string name
) : base(name
,md
)
4232 tabIx
= MDTable
.AssemblyRef
;
4236 /// Add version information about this external assembly
4238 /// <param name="majVer">Major Version</param>
4239 /// <param name="minVer">Minor Version</param>
4240 /// <param name="bldNo">Build Number</param>
4241 /// <param name="revNo">Revision Number</param>
4242 public void AddVersionInfo(int majVer
, int minVer
, int bldNo
, int revNo
)
4244 major
= (ushort)majVer
;
4245 minor
= (ushort)minVer
;
4246 build
= (ushort)bldNo
;
4247 revision
= (ushort)revNo
;
4252 /// Add the hash value for this external assembly
4254 /// <param name="hash">bytes of the hash value</param>
4255 public void AddHash(byte[] hash
)
4257 hashIx
= metaData
.AddToBlobHeap(hash
);
4261 /// Set the culture for this external assembly
4263 /// <param name="cult">the culture string</param>
4264 public void AddCulture(string cult
)
4266 cultIx
= metaData
.AddToStringsHeap(cult
);
4271 /// Add the full public key for this external assembly
4273 /// <param name="key">bytes of the public key</param>
4274 public void AddKey(byte[] key
)
4276 flags
|= 0x0001; // full public key
4278 keyIx
= metaData
.AddToBlobHeap(key
);
4282 /// Add the public key token (low 8 bytes of the public key)
4284 /// <param name="key">low 8 bytes of public key</param>
4285 public void AddKeyToken(byte[] key
)
4287 keyIx
= metaData
.AddToBlobHeap(key
);
4293 /// Add a class to this external assembly
4295 /// <param name="nsName">name space name</param>
4296 /// <param name="name">class name</param>
4297 /// <returns></returns>
4298 public virtual ClassRef
AddClass(string nsName
, string name
)
4300 ClassRef aClass
= new ClassRef(nsName
,name
,metaData
);
4301 metaData
.AddToTable(MDTable
.TypeRef
,aClass
);
4302 aClass
.SetParent(this);
4307 /// Add a value class to this external assembly
4309 /// <param name="nsName">name space name</param>
4310 /// <param name="name">class name</param>
4311 /// <returns></returns>
4312 public virtual ClassRef
AddValueClass(string nsName
, string name
)
4314 ClassRef aClass
= new ClassRef(nsName
,name
,metaData
);
4315 metaData
.AddToTable(MDTable
.TypeRef
,aClass
);
4316 aClass
.SetParent(this);
4317 aClass
.MakeValueClass(ValueClass
.ValueType
);
4321 internal string TypeName()
4323 string result
= name
;
4325 result
= result
+ ", Version=" + major
+ "." + minor
+ "." +
4326 build
+ "." + revision
;
4327 if (keyBytes
!= null) {
4328 string tokenStr
= "=";
4329 if (isKeyToken
) tokenStr
= "Token=";
4330 result
= result
+ ", PublicKey" + tokenStr
;
4331 for (int i
=0; i
< keyBytes
.Length
; i
++) {
4332 result
= result
+ Hex
.Byte(keyBytes
[i
]);
4335 if (culture
!= null)
4336 result
= result
+ ", Culture=" + culture
;
4340 internal sealed override uint Size(MetaData md
)
4342 return 12 + 2 * md
.StringsIndexSize() + 2 * md
.BlobIndexSize();
4345 internal sealed override void Write(FileImage output
)
4347 output
.Write(major
);
4348 output
.Write(minor
);
4349 output
.Write(build
);
4350 output
.Write(revision
);
4351 output
.Write(flags
);
4352 output
.BlobIndex(keyIx
);
4353 output
.StringsIndex(nameIx
);
4354 output
.StringsIndex(cultIx
);
4355 output
.BlobIndex(hashIx
);
4358 internal sealed override uint GetCodedIx(CIx code
)
4361 case (CIx
.ResolutionScope
) : return 2;
4362 case (CIx
.HasCustomAttr
) : return 15;
4363 case (CIx
.Implementation
) : return 1;
4370 /**************************************************************************/
4372 /// Descriptor for a class defined in System (mscorlib)
4374 internal class SystemClass
: ClassRef
{
4376 PrimitiveType elemType
;
4378 internal SystemClass(PrimitiveType eType
, AssemblyRef paren
, MetaData md
)
4379 : base("System",eType
.GetName(),md
) {
4384 internal override sealed MetaDataElement
GetTypeSpec(MetaData md
)
4386 if (typeSpec
== null) typeSpec
= (TypeSpec
)elemType
.GetTypeSpec(md
);
4391 internal sealed override void TypeSig(MemoryStream str
)
4393 str
.WriteByte(elemType
.GetTypeIndex());
4398 /**************************************************************************/
4400 /// The assembly for mscorlib.
4402 public sealed class MSCorLib
: AssemblyRef
{
4404 private static readonly int valueTypeIx
= 18;
4405 private readonly string systemName
= "System";
4406 private Class
[] systemClasses
= new Class
[valueTypeIx
+2];
4407 private PrimitiveType
[] systemTypes
= new PrimitiveType
[valueTypeIx
];
4408 private TypeSpec
[] specialTypeSpecs
= new TypeSpec
[valueTypeIx
];
4409 private static int[] specialNames
= {
4410 PrimitiveType
.Void
.GetName().GetHashCode(),
4411 PrimitiveType
.Boolean
.GetName().GetHashCode(),
4412 PrimitiveType
.Char
.GetName().GetHashCode(),
4413 PrimitiveType
.Int8
.GetName().GetHashCode(),
4414 PrimitiveType
.UInt8
.GetName().GetHashCode(),
4415 PrimitiveType
.Int16
.GetName().GetHashCode(),
4416 PrimitiveType
.UInt16
.GetName().GetHashCode(),
4417 PrimitiveType
.Int32
.GetName().GetHashCode(),
4418 PrimitiveType
.UInt32
.GetName().GetHashCode(),
4419 PrimitiveType
.Int64
.GetName().GetHashCode(),
4420 PrimitiveType
.UInt64
.GetName().GetHashCode(),
4421 PrimitiveType
.Float32
.GetName().GetHashCode(),
4422 PrimitiveType
.Float64
.GetName().GetHashCode(),
4423 PrimitiveType
.String
.GetName().GetHashCode(),
4424 PrimitiveType
.TypedRef
.GetName().GetHashCode(),
4425 PrimitiveType
.IntPtr
.GetName().GetHashCode(),
4426 PrimitiveType
.UIntPtr
.GetName().GetHashCode(),
4427 PrimitiveType
.Object
.GetName().GetHashCode(),
4428 PrimitiveType
.ValueType
.GetName ().GetHashCode(),
4429 "Enum".GetHashCode()
4432 internal MSCorLib(MetaData md
) : base(md
,"mscorlib")
4434 if (!PEFile
.IsMSCorlib
)
4435 md
.AddToTable(MDTable
.AssemblyRef
,this);
4436 systemTypes
[PrimitiveType
.Void
.GetSystemTypeIx()] = PrimitiveType
.Void
;
4437 systemTypes
[PrimitiveType
.Boolean
.GetSystemTypeIx()] = PrimitiveType
.Boolean
;
4438 systemTypes
[PrimitiveType
.Char
.GetSystemTypeIx()] = PrimitiveType
.Char
;
4439 systemTypes
[PrimitiveType
.Int8
.GetSystemTypeIx()] = PrimitiveType
.Int8
;
4440 systemTypes
[PrimitiveType
.UInt8
.GetSystemTypeIx()] = PrimitiveType
.UInt8
;
4441 systemTypes
[PrimitiveType
.Int16
.GetSystemTypeIx()] = PrimitiveType
.Int16
;
4442 systemTypes
[PrimitiveType
.UInt16
.GetSystemTypeIx()] = PrimitiveType
.UInt16
;
4443 systemTypes
[PrimitiveType
.Int32
.GetSystemTypeIx()] = PrimitiveType
.Int32
;
4444 systemTypes
[PrimitiveType
.UInt32
.GetSystemTypeIx()] = PrimitiveType
.UInt32
;
4445 systemTypes
[PrimitiveType
.Int64
.GetSystemTypeIx()] = PrimitiveType
.Int64
;
4446 systemTypes
[PrimitiveType
.UInt64
.GetSystemTypeIx()] = PrimitiveType
.UInt64
;
4447 systemTypes
[PrimitiveType
.Float32
.GetSystemTypeIx()] = PrimitiveType
.Float32
;
4448 systemTypes
[PrimitiveType
.Float64
.GetSystemTypeIx()] = PrimitiveType
.Float64
;
4449 systemTypes
[PrimitiveType
.IntPtr
.GetSystemTypeIx()] = PrimitiveType
.IntPtr
;
4450 systemTypes
[PrimitiveType
.UIntPtr
.GetSystemTypeIx()] = PrimitiveType
.UIntPtr
;
4451 systemTypes
[PrimitiveType
.String
.GetSystemTypeIx()] = PrimitiveType
.String
;
4452 systemTypes
[PrimitiveType
.Object
.GetSystemTypeIx()] = PrimitiveType
.Object
;
4453 systemTypes
[PrimitiveType
.TypedRef
.GetSystemTypeIx()] = PrimitiveType
.TypedRef
;
4457 /// Add a class to the mscorlib assembly
4459 /// <param name="nsName">name space name</param>
4460 /// <param name="name">class name</param>
4461 /// <returns></returns>
4462 public override ClassRef
AddClass(string nsName
, string name
)
4464 /* This gets called by !mscorlib, for adding references INTO mscorlib, so
4465 it should be returning ClassRef ..*/
4466 Class aClass
= GetSpecialClass(nsName
,name
);
4467 if (aClass
== null) {
4468 aClass
= new ClassRef(nsName
,name
,metaData
);
4469 metaData
.AddToTable(MDTable
.TypeRef
,aClass
);
4470 if (aClass
is ClassRef
)
4471 ((ClassRef
) aClass
).SetParent(this);
4473 //FIXME: Check for !ClassRef here?
4474 return (ClassRef
) aClass
;
4477 private Class
GetSpecialClass(string nsName
,string name
)
4479 if (nsName
.CompareTo(systemName
) != 0) return null;
4480 int hash
= name
.GetHashCode();
4481 for (int i
=0; i
< specialNames
.Length
; i
++) {
4482 if (hash
!= specialNames
[i
])
4484 if (systemClasses
[i
] == null) {
4485 if (i
< valueTypeIx
) {
4486 systemClasses
[i
] = new SystemClass(systemTypes
[i
],this,metaData
);
4487 if ((systemTypes
[i
] != PrimitiveType
.Object
) &&
4488 (systemTypes
[i
] != PrimitiveType
.String
)) {
4489 systemClasses
[i
].MakeValueClass(ValueClass
.ValueType
);
4492 systemClasses
[i
] = new ClassRef(nsName
,name
,metaData
);
4493 ((ClassRef
) systemClasses
[i
]).SetParent(this);
4494 if (!ClassDef
.IsValueType (nsName
, name
) && !ClassDef
.IsEnum (nsName
, name
))
4495 systemClasses
[i
].MakeValueClass(ValueClass
.ValueType
);
4497 metaData
.AddToTable(MDTable
.TypeRef
,systemClasses
[i
]);
4499 return systemClasses
[i
];
4504 internal void SetSpecialSystemClass (string nsName
, string name
, Class aClass
)
4506 if (nsName
!= systemName
) return;
4507 int hash
= name
.GetHashCode ();
4508 for (int i
= 0; i
< specialNames
.Length
; i
++) {
4509 if (hash
!= specialNames
[i
])
4511 if (systemClasses
[i
] == null) {
4512 systemClasses
[i
] = aClass
;
4517 internal Class
GetSpecialSystemClass(PrimitiveType pType
)
4519 int ix
= pType
.GetSystemTypeIx();
4520 if (systemClasses
[ix
] == null && !PEFile
.IsMSCorlib
) {
4521 systemClasses
[ix
] = new SystemClass(pType
,this,metaData
);
4522 metaData
.AddToTable(MDTable
.TypeRef
,systemClasses
[ix
]);
4524 return systemClasses
[ix
];
4527 private ClassRef
GetValueClass(string name
, int hash
)
4529 /* Called by MSCorLib.AddValueClass, which is called by
4530 !mscorlib, for adding ref to value class INTO mscorlib,
4531 so this should be classref */
4532 int ix
= valueTypeIx
;
4533 if (hash
!= specialNames
[valueTypeIx
]) ix
++;
4534 if (systemClasses
[ix
] == null) {
4535 systemClasses
[ix
] = new ClassRef(systemName
,name
,metaData
);
4536 ((ClassRef
) systemClasses
[ix
]).SetParent(this);
4537 ((ClassRef
) systemClasses
[ix
]).MakeValueClass(ValueClass
.ValueType
);
4538 metaData
.AddToTable(MDTable
.TypeRef
,systemClasses
[ix
]);
4540 return (ClassRef
) systemClasses
[ix
];
4543 internal Class
ValueType()
4545 if (systemClasses
[valueTypeIx
] == null && !PEFile
.IsMSCorlib
) {
4546 ClassRef valType
= new ClassRef("System","ValueType",metaData
);
4547 valType
.SetParent(this);
4548 valType
.MakeValueClass(ValueClass
.ValueType
);
4549 metaData
.AddToTable(MDTable
.TypeRef
,valType
);
4550 systemClasses
[valueTypeIx
] = valType
;
4552 return systemClasses
[valueTypeIx
];
4555 internal Class
EnumType()
4557 /* Called by both mscorlib & !mscorlib, so can be
4558 either ClassRef or ClassDef */
4559 //systemClasses [ valueTypeIx + 1] -> System.Enum
4560 if (systemClasses
[valueTypeIx
+ 1] == null && !PEFile
.IsMSCorlib
) {
4561 ClassRef valType
= new ClassRef("System","Enum",metaData
);
4562 valType
.SetParent(this);
4563 valType
.MakeValueClass(ValueClass
.Enum
);
4564 metaData
.AddToTable(MDTable
.TypeRef
,valType
);
4565 systemClasses
[valueTypeIx
+ 1] = valType
;
4567 return systemClasses
[valueTypeIx
+ 1];
4571 /// Add a value class to this external assembly
4573 /// <param name="nsName">name space name</param>
4574 /// <param name="name">class name</param>
4575 /// <returns></returns>
4576 public override ClassRef
AddValueClass(string nsName
, string name
)
4578 if (nsName
.CompareTo(systemName
) == 0) {
4579 int hash
= name
.GetHashCode();
4580 if ((hash
== specialNames
[valueTypeIx
]) ||
4581 (hash
== specialNames
[valueTypeIx
+1])) {
4582 return GetValueClass(name
,hash
);
4585 ClassRef aClass
= new ClassRef(nsName
,name
,metaData
);
4586 metaData
.AddToTable(MDTable
.TypeRef
,aClass
);
4587 aClass
.SetParent(this);
4588 aClass
.MakeValueClass(ValueClass
.ValueType
);
4594 /**************************************************************************/
4597 /// Root (20 bytes + UTF-8 Version String + quad align padding)
4598 /// StreamHeaders (8 bytes + null terminated name string + quad align padding)
4600 /// #~ (always present - holds metadata tables)
4601 /// #Strings (always present - holds identifier strings)
4602 /// #US (Userstring heap)
4603 /// #Blob (signature blobs)
4604 /// #GUID (guids for assemblies or Modules)
4606 public class MetaData
{
4608 internal static readonly int[] CIxShiftMap
= {2,2,5,1,2,3,1,1,1,2,3,2,1}
;
4609 private static readonly byte StringsHeapMask
= 0x1;
4610 private static readonly byte GUIDHeapMask
= 0x2;
4611 private static readonly byte BlobHeapMask
= 0x4;
4612 private static readonly uint MetaDataSignature
= 0x424A5342;
4613 private static readonly uint maxSmlIxSize
= 0xFFFF;
4614 private static readonly uint max1BitSmlIx
= 0x7FFF;
4615 private static readonly uint max2BitSmlIx
= 0x3FFF;
4616 private static readonly uint max3BitSmlIx
= 0x1FFF;
4617 private static readonly uint max5BitSmlIx
= 0x7FF;
4618 // NOTE: version and stream name strings MUST always be quad padded
4619 #if NET_2_0 || BOOTSTRAP_NET_2_0
4620 private static readonly string version
= "v2.0.50727\0\0";
4622 private static readonly string version
= "v1.1.4322\0\0\0";
4624 private static readonly char[] tildeName
= {'#','~','\0','\0'}
;
4625 private static readonly char[] stringsName
= {'#','S','t','r','i','n','g','s','\0','\0','\0','\0'}
;
4626 private static readonly char[] usName
= {'#','U','S','\0'}
;
4627 private static readonly char[] guidName
= {'#','G','U','I','D','\0','\0','\0'}
;
4628 private static readonly char[] blobName
= {'#','B','l','o','b','\0','\0','\0'}
;
4629 private static readonly uint MetaDataHeaderSize
= 20 + (uint)version
.Length
;
4630 private static readonly uint TildeHeaderSize
= 24;
4631 private static readonly uint StreamHeaderSize
= 8;
4632 private static readonly uint numMetaDataTables
= (int)MDTable
.GenericParamConstraint
+ 1;
4633 private static readonly uint tildeHeaderSize
= 8 + (uint)tildeName
.Length
;
4635 MetaDataStream strings
, us
, guid
, blob
;
4637 MetaDataStream
[] streams
= new MetaDataStream
[5];
4638 uint numStreams
= 5;
4639 uint tildeTide
= 0, tildePadding
= 0, tildeStart
= 0;
4640 uint numTables
= 0, resourcesSize
= 0;
4641 ArrayList
[] metaDataTables
= new ArrayList
[numMetaDataTables
];
4642 ArrayList byteCodes
= new ArrayList();
4643 uint codeSize
= 0, codeStart
, byteCodePadding
= 0, metaDataSize
= 0;
4644 ulong valid
= 0, /*sorted = 0x000002003301FA00;*/ sorted
= 0;
4645 bool[] largeIx
= new bool[numMetaDataTables
];
4646 bool[] lgeCIx
= new bool[(int)CIx
.MaxCIx
];
4647 bool largeStrings
= false, largeUS
= false, largeGUID
= false, largeBlob
= false;
4648 private FileImage file
;
4649 private byte heapSizes
= 0;
4650 MetaDataElement entryPoint
;
4651 BinaryWriter output
;
4652 public MSCorLib mscorlib
;
4653 private TypeSpec
[] systemTypeSpecs
= new TypeSpec
[PrimitiveType
.NumSystemTypes
];
4655 private ArrayList cattr_list
;
4656 private ArrayList declsec_list
;
4657 ArrayList resources
;
4659 internal MetaData(FileImage file
)
4661 // tilde = new MetaDataStream(tildeName,false,0);
4663 strings
= new MetaDataStream(stringsName
,new UTF8Encoding(),true);
4664 us
= new MetaDataStream(usName
,new UnicodeEncoding(),true);
4665 guid
= new MetaDataStream(guidName
,false);
4666 blob
= new MetaDataStream(blobName
,true);
4667 streams
[1] = strings
;
4671 for (int i
=0; i
< numMetaDataTables
; i
++) {
4674 for (int i
=0; i
< lgeCIx
.Length
; i
++) {
4677 mscorlib
= new MSCorLib(this);
4680 internal TypeSpec
GetPrimitiveTypeSpec(int ix
)
4682 return systemTypeSpecs
[ix
];
4685 internal void SetPrimitiveTypeSpec(int ix
, TypeSpec typeSpec
)
4687 systemTypeSpecs
[ix
] = typeSpec
;
4690 internal uint Size()
4692 return metaDataSize
;
4695 private void CalcHeapSizes ()
4697 if (strings
.LargeIx()) {
4698 largeStrings
= true;
4699 heapSizes
|= StringsHeapMask
;
4701 if (guid
.LargeIx()) {
4703 heapSizes
|= GUIDHeapMask
;
4705 if (blob
.LargeIx()) {
4707 heapSizes
|= BlobHeapMask
;
4710 largeUS
= us
.LargeIx();
4713 internal void StreamSize(byte mask
)
4718 internal uint AddToUSHeap(string str
)
4720 if (str
== null) return 0;
4721 return us
.Add(str
,true);
4724 internal uint AddToUSHeap(byte[] str
)
4726 if (str
== null) return 0;
4727 return us
.Add (str
, true);
4730 internal uint AddToStringsHeap(string str
)
4732 if ((str
== null) || (str
.CompareTo("") == 0)) return 0;
4733 return strings
.Add(str
,false);
4736 internal uint AddToGUIDHeap(Guid guidNum
)
4738 return guid
.Add(guidNum
, false);
4741 internal uint AddToBlobHeap(byte[] blobBytes
)
4743 if (blobBytes
== null) return 0;
4744 return blob
.Add(blobBytes
, true);
4747 internal uint AddToBlobHeap(byte val
)
4749 return blob
.Add(val
, true);
4752 internal uint AddToBlobHeap(sbyte val
)
4754 return blob
.Add(val
, true);
4757 internal uint AddToBlobHeap(ushort val
)
4759 return blob
.Add(val
, true);
4762 internal uint AddToBlobHeap(short val
)
4764 return blob
.Add(val
, true);
4767 internal uint AddToBlobHeap(uint val
)
4769 return blob
.Add(val
, true);
4772 internal uint AddToBlobHeap(int val
)
4774 return blob
.Add(val
, true);
4777 internal uint AddToBlobHeap(ulong val
)
4779 return blob
.Add(val
, true);
4782 internal uint AddToBlobHeap(long val
)
4784 return blob
.Add(val
, true);
4787 internal uint AddToBlobHeap(float val
)
4789 return blob
.Add(val
, true);
4792 internal uint AddToBlobHeap(double val
)
4794 return blob
.Add(val
, true);
4797 internal uint AddToBlobHeap(string val
)
4799 return blob
.Add(val
,true);
4802 internal void AddCustomAttribute (CustomAttribute cattr
)
4804 if (cattr_list
== null)
4805 cattr_list
= new ArrayList ();
4806 cattr_list
.Add (cattr
);
4809 internal void AddDeclSecurity (DeclSecurity decl_sec
)
4811 if (declsec_list
== null)
4812 declsec_list
= new ArrayList ();
4813 declsec_list
.Add (decl_sec
);
4816 private ArrayList
GetTable(MDTable tableIx
)
4818 int tabIx
= (int)tableIx
;
4819 if (metaDataTables
[tabIx
] == null) {
4820 metaDataTables
[tabIx
] = new ArrayList();
4821 valid
|= ((ulong)0x1 << tabIx
);
4822 // Console.WriteLine("after creating table " + tableIx + "(" + tabIx + ") valid = " + valid);
4825 return metaDataTables
[tabIx
];
4828 internal void AddToTable(MDTable tableIx
, MetaDataElement elem
)
4831 // Console.Out.WriteLine("ERROR - element already in table " + tableIx);
4834 // updates Row field of the element
4835 // Console.WriteLine("Adding element to table " + (uint)tableIx);
4836 ArrayList table
= GetTable(tableIx
);
4837 elem
.Row
= (uint)table
.Count
+ 1;
4841 internal uint TableIndex(MDTable tableIx
)
4843 if (metaDataTables
[(int)tableIx
] == null) return 1;
4844 return (uint)metaDataTables
[(int)tableIx
].Count
+1;
4847 internal uint AddCode(CILInstructions byteCode
)
4849 byteCodes
.Add(byteCode
);
4850 uint offset
= codeSize
+ codeStart
;
4851 codeSize
+= byteCode
.GetCodeSize();
4855 internal void SetEntryPoint(MetaDataElement ep
)
4860 internal uint AddResource(byte[] resBytes
)
4862 if (resources
== null) resources
= new ArrayList ();
4863 resources
.Add (resBytes
);
4864 uint offset
= resourcesSize
;
4865 resourcesSize
+= (uint)resBytes
.Length
+ 4;
4869 internal void AddData(DataConstant cVal
)
4871 file
.AddInitData(cVal
);
4874 internal static void CompressNum(uint val
, MemoryStream sig
)
4877 sig
.WriteByte((byte)val
);
4878 } else if (val
< 0x3FFF) {
4879 byte b1
= (byte)((val
>> 8) | 0x80);
4880 byte b2
= (byte)(val
& FileImage
.iByteMask
[0]);
4884 byte b1
= (byte)((val
>> 24) | 0xC0);
4885 byte b2
= (byte)((val
& FileImage
.iByteMask
[2]) >> 16);
4886 byte b3
= (byte)((val
& FileImage
.iByteMask
[1]) >> 8);;
4887 byte b4
= (byte)(val
& FileImage
.iByteMask
[0]);
4895 internal uint CodeSize()
4897 return codeSize
+ byteCodePadding
;
4900 internal uint GetResourcesSize()
4902 return resourcesSize
;
4905 internal uint StringsIndexSize()
4907 if (largeStrings
) return 4;
4911 internal uint GUIDIndexSize()
4913 if (largeGUID
) return 4;
4917 internal uint USIndexSize()
4919 if (largeUS
) return 4;
4923 internal uint BlobIndexSize()
4925 if (largeBlob
) return 4;
4929 internal uint CodedIndexSize(CIx code
)
4931 if (lgeCIx
[(uint)code
]) return 4;
4935 internal uint TableIndexSize(MDTable tabIx
)
4937 if (largeIx
[(uint)tabIx
]) return 4;
4941 private void SetIndexSizes()
4943 for (int i
=0; i
< numMetaDataTables
; i
++) {
4944 if (metaDataTables
[i
] == null)
4947 uint count
= (uint)metaDataTables
[i
].Count
;
4948 if (count
> maxSmlIxSize
)
4951 MDTable tabIx
= (MDTable
)i
;
4952 if (count
> max5BitSmlIx
) {
4953 lgeCIx
[(int)CIx
.HasCustomAttr
] = true;
4955 if (count
> max3BitSmlIx
) {
4956 if ((tabIx
== MDTable
.TypeRef
) || (tabIx
== MDTable
.ModuleRef
) || (tabIx
== MDTable
.Method
) || (tabIx
== MDTable
.TypeSpec
) || (tabIx
== MDTable
.Field
))
4957 lgeCIx
[(int)CIx
.CustomAttributeType
] = true;
4958 if ((tabIx
== MDTable
.Method
) || (tabIx
== MDTable
.MemberRef
))
4959 lgeCIx
[(int)CIx
.MemberRefParent
] = true;
4961 if (count
> max2BitSmlIx
) {
4962 if ((tabIx
== MDTable
.Field
) || (tabIx
== MDTable
.Param
) || (tabIx
== MDTable
.Property
))
4963 lgeCIx
[(int)CIx
.HasConst
] = true;
4964 if ((tabIx
== MDTable
.TypeDef
) || (tabIx
== MDTable
.TypeRef
) || (tabIx
== MDTable
.TypeSpec
))
4965 lgeCIx
[(int)CIx
.TypeDefOrRef
] = true;
4966 if ((tabIx
== MDTable
.TypeDef
) || (tabIx
== MDTable
.Method
) || (tabIx
== MDTable
.Assembly
))
4967 lgeCIx
[(int)CIx
.HasDeclSecurity
] = true;
4968 if ((tabIx
== MDTable
.File
) || (tabIx
== MDTable
.AssemblyRef
) || (tabIx
== MDTable
.ExportedType
))
4969 lgeCIx
[(int)CIx
.Implementation
] = true;
4970 if ((tabIx
== MDTable
.Module
) || (tabIx
== MDTable
.ModuleRef
) || (tabIx
== MDTable
.AssemblyRef
) || (tabIx
== MDTable
.TypeRef
))
4971 lgeCIx
[(int)CIx
.ResolutionScope
] = true;
4973 if (count
> max1BitSmlIx
) {
4974 if ((tabIx
== MDTable
.Field
) || (tabIx
== MDTable
.Param
))
4975 lgeCIx
[(int)CIx
.HasFieldMarshal
] = true;
4976 if ((tabIx
== MDTable
.Event
) || (tabIx
== MDTable
.Property
))
4977 lgeCIx
[(int)CIx
.HasSemantics
] = true;
4978 if ((tabIx
== MDTable
.Method
) || (tabIx
== MDTable
.MemberRef
))
4979 lgeCIx
[(int)CIx
.MethodDefOrRef
] = true;
4980 if ((tabIx
== MDTable
.Field
) || (tabIx
== MDTable
.Method
))
4981 lgeCIx
[(int)CIx
.MemberForwarded
] = true;
4982 if ((tabIx
== MDTable
.TypeDef
) || (tabIx
== MDTable
.Method
))
4983 lgeCIx
[(int)CIx
.TypeOrMethodDef
] = true;
4988 private void SetStreamOffsets()
4990 uint sizeOfHeaders
= StreamHeaderSize
+ (uint)tildeName
.Length
;
4991 for (int i
=1; i
< numStreams
; i
++) {
4992 sizeOfHeaders
+= streams
[i
].headerSize();
4994 metaDataSize
= MetaDataHeaderSize
+ sizeOfHeaders
;
4995 tildeStart
= metaDataSize
;
4996 metaDataSize
+= tildeTide
+ tildePadding
;
4997 for (int i
=1; i
< numStreams
; i
++) {
4998 streams
[i
].Start
= metaDataSize
;
4999 metaDataSize
+= streams
[i
].Size();
5000 streams
[i
].WriteDetails();
5004 internal void CalcTildeStreamSize()
5007 //tilde.SetIndexSizes(strings.LargeIx(),us.LargeIx(),guid.LargeIx(),blob.LargeIx());
5008 tildeTide
= TildeHeaderSize
;
5009 tildeTide
+= 4 * numTables
;
5010 //Console.WriteLine("Tilde header + sizes = " + tildeTide);
5011 for (int i
=0; i
< numMetaDataTables
; i
++) {
5012 if (metaDataTables
[i
] != null) {
5013 ArrayList table
= metaDataTables
[i
];
5014 // Console.WriteLine("Meta data table " + i + " at offset " + tildeTide);
5015 tildeTide
+= (uint)table
.Count
* ((MetaDataElement
)table
[0]).Size(this);
5016 // Console.WriteLine("Metadata table " + i + " has size " + table.Count);
5017 // Console.WriteLine("tildeTide = " + tildeTide);
5020 if ((tildeTide
% 4) != 0) tildePadding
= 4 - (tildeTide
% 4);
5021 //Console.WriteLine("tildePadding = " + tildePadding);
5024 internal void WriteTildeStream(FileImage output
)
5026 long startTilde
= output
.Seek(0,SeekOrigin
.Current
);
5027 output
.Write((uint)0); // Reserved
5028 #if NET_2_0 || BOOTSTRAP_NET_2_0
5029 output
.Write((byte)2); // MajorVersion
5030 output
.Write((byte)0); // MinorVersion
5032 output
.Write((byte)1); // MajorVersion
5033 output
.Write((byte)0); // MinorVersion
5035 output
.Write(heapSizes
);
5036 output
.Write((byte)1); // Reserved
5037 output
.Write(valid
);
5038 output
.Write(sorted
);
5039 for (int i
=0; i
< numMetaDataTables
; i
++) {
5040 if (metaDataTables
[i
] != null) {
5041 uint count
= (uint)metaDataTables
[i
].Count
;
5042 output
.Write(count
);
5045 long tabStart
= output
.Seek(0,SeekOrigin
.Current
);
5046 // Console.WriteLine("Starting metaData tables at " + tabStart);
5047 for (int i
=0; i
< numMetaDataTables
; i
++) {
5048 if (metaDataTables
[i
] != null) {
5049 // Console.WriteLine("Starting metaData table " + i + " at " + (output.Seek(0,SeekOrigin.Current) - startTilde));
5050 ArrayList table
= metaDataTables
[i
];
5051 for (int j
=0; j
< table
.Count
; j
++) {
5052 ((MetaDataElement
)table
[j
]).Write(output
);
5056 // Console.WriteLine("Writing padding at " + output.Seek(0,SeekOrigin.Current));
5057 for (int i
=0; i
< tildePadding
; i
++) output
.Write((byte)0);
5060 private void BuildTable(ArrayList table
)
5062 if (table
== null) return;
5063 for (int j
=0; j
< table
.Count
; j
++) {
5064 ((MetaDataElement
)table
[j
]).BuildTables(this);
5068 private void SortTable (ArrayList mTable
)
5070 if (mTable
== null) return;
5072 for (int i
=0; i
< mTable
.Count
; i
++) {
5073 ((MetaDataElement
)mTable
[i
]).Row
= (uint)i
+1;
5077 internal void BuildMetaData(uint codeStartOffset
)
5079 codeStart
= codeStartOffset
;
5080 BuildTable(metaDataTables
[(int)MDTable
.TypeDef
]);
5081 BuildTable(metaDataTables
[(int)MDTable
.TypeSpec
]);
5082 BuildTable(metaDataTables
[(int)MDTable
.MemberRef
]);
5083 #if NET_2_0 || BOOTSTRAP_NET_2_0
5084 BuildTable(metaDataTables
[(int)MDTable
.GenericParam
]);
5085 BuildTable(metaDataTables
[(int)MDTable
.MethodSpec
]);
5086 BuildTable(metaDataTables
[(int)MDTable
.GenericParamConstraint
]);
5088 BuildTable(metaDataTables
[(int)MDTable
.ManifestResource
]);
5090 if (cattr_list
!= null) {
5091 foreach (CustomAttribute cattr
in cattr_list
)
5092 cattr
.BuildTables (this);
5095 if (declsec_list
!= null) {
5096 foreach (DeclSecurity decl_sec
in declsec_list
)
5097 decl_sec
.BuildTables (this);
5100 /* for (int i=0; i < metaDataTables.Length; i++) {
5101 ArrayList table = metaDataTables[i];
5102 if (table != null) {
5103 for (int j=0; j < table.Count; j++) {
5104 ((MetaDataElement)table[j]).BuildTables(this);
5111 for (int i
=1; i
< numStreams
; i
++) {
5112 streams
[i
].EndStream();
5114 CalcTildeStreamSize();
5116 byteCodePadding
= NumToAlign(codeSize
,4);
5117 if (entryPoint
!= null) file
.SetEntryPoint(entryPoint
.Token());
5119 // Check ordering of specific tables
5120 // Constant, CustomAttribute, FieldMarshal, DeclSecurity, MethodSemantics
5121 // ImplMap, GenericParam
5122 // Need to load GenericParamConstraint AFTER GenericParam table in correct order
5124 // InterfaceImpl, ClassLayout, FieldLayout, MethodImpl, FieldRVA, NestedClass
5125 // will _ALWAYS_ be in the correct order as embedded in BuildMDTables
5127 SortTable(metaDataTables
[(int)MDTable
.Constant
]);
5128 SortTable(metaDataTables
[(int)MDTable
.CustomAttribute
]);
5129 SortTable(metaDataTables
[(int)MDTable
.FieldMarshal
]);
5130 SortTable(metaDataTables
[(int)MDTable
.DeclSecurity
]);
5131 SortTable(metaDataTables
[(int)MDTable
.MethodSemantics
]);
5132 SortTable(metaDataTables
[(int)MDTable
.ImplMap
]);
5133 #if NET_2_0 || BOOTSTRAP_NET_2_0
5134 if (metaDataTables
[(int)MDTable
.GenericParam
] != null) {
5135 SortTable(metaDataTables
[(int)MDTable
.GenericParam
]);
5136 // Now add GenericParamConstraints
5137 /*for (int i=0; i < metaDataTables[(int)MDTable.GenericParam].Count; i++) {
5138 ((GenericParameter)metaDataTables[(int)MDTable.GenericParam][i]).AddConstraints(this);
5141 SortTable(metaDataTables
[(int)MDTable
.GenericParamConstraint
]);
5143 SortTable(metaDataTables
[(int)MDTable
.InterfaceImpl
]);
5147 internal void WriteByteCodes(FileImage output
)
5149 for (int i
=0; i
< byteCodes
.Count
; i
++) {
5150 ((CILInstructions
)byteCodes
[i
]).Write(output
);
5152 for (int i
=0; i
< byteCodePadding
; i
++) {
5153 output
.Write((byte)0);
5157 internal void WriteResources (FileImage output
)
5159 if (resources
== null) return;
5160 for (int i
= 0; i
< resources
.Count
; i
++) {
5161 byte [] resBytes
= (byte []) resources
[i
];
5162 output
.Write ((uint) resBytes
.Length
);
5163 output
.Write (resBytes
);
5167 internal void WriteMetaData(FileImage output
)
5169 this.output
= output
;
5170 mdStart
= output
.Seek(0,SeekOrigin
.Current
);
5171 // Console.WriteLine("Writing metaData at " + Hex.Long(mdStart));
5172 output
.Write(MetaDataSignature
);
5173 output
.Write((short)1); // Major Version
5174 output
.Write((short)1); // Minor Version ECMA = 0, PEFiles = 1
5175 output
.Write(0); // Reserved
5176 output
.Write(version
.Length
);
5177 output
.Write(version
.ToCharArray()); // version string is already zero padded
5178 output
.Write((short)0);
5179 output
.Write((ushort)numStreams
);
5180 // write tilde header
5181 output
.Write(tildeStart
);
5182 output
.Write(tildeTide
+ tildePadding
);
5183 output
.Write(tildeName
);
5184 for (int i
=1; i
< numStreams
; i
++) streams
[i
].WriteHeader(output
);
5185 // Console.WriteLine("Writing tilde stream at " + output.Seek(0,SeekOrigin.Current) + " = " + tildeStart);
5186 WriteTildeStream(output
);
5187 for (int i
=1; i
< numStreams
; i
++) streams
[i
].Write(output
);
5188 // Console.WriteLine("Finished Writing metaData at " + output.Seek(0,SeekOrigin.Current));
5191 internal bool LargeStringsIndex() { return strings.LargeIx(); }
5192 internal bool LargeGUIDIndex() { return guid.LargeIx(); }
5193 internal bool LargeUSIndex() { return us.LargeIx(); }
5194 internal bool LargeBlobIndex() { return blob.LargeIx(); }
5196 internal bool LargeIx(MDTable tabIx
) { return largeIx[(uint)tabIx]; }
5199 private uint NumToAlign(uint val
, uint alignVal
)
5201 if ((val
% alignVal
) == 0) return 0;
5202 return alignVal
- (val
% alignVal
);
5205 internal void WriteCodedIndex(CIx code
, MetaDataElement elem
, FileImage output
)
5209 ix
= (elem
.Row
<< CIxShiftMap
[(uint)code
]) | elem
.GetCodedIx(code
);
5210 // Console.WriteLine("coded index = " + ix + " row = " + elem.Row);
5212 // Console.WriteLine("elem for coded index is null");
5214 if (lgeCIx
[(uint)code
])
5217 output
.Write((ushort)ix
);
5222 /**************************************************************************/
5224 /// Stream in the Meta Data (#Strings, #US, #Blob and #GUID)
5227 internal class MetaDataStream
: BinaryWriter
{
5229 private static readonly uint StreamHeaderSize
= 8;
5230 private static uint maxSmlIxSize
= 0xFFFF;
5232 private uint start
= 0;
5233 uint size
= 0, tide
= 1;
5234 bool largeIx
= false;
5237 Hashtable htable
= new Hashtable();
5238 Hashtable btable
= new Hashtable (new ByteArrayHashCodeProvider (), new ByteArrayComparer ());
5240 internal MetaDataStream(char[] name
, bool addInitByte
) : base(new MemoryStream())
5242 if (addInitByte
) { Write((byte)0); size = 1; }
5244 sizeOfHeader
= StreamHeaderSize
+ (uint)name
.Length
;
5247 internal MetaDataStream(char[] name
, System
.Text
.Encoding enc
, bool addInitByte
) : base(new MemoryStream(),enc
)
5249 if (addInitByte
) { Write((byte)0); size = 1; }
5251 sizeOfHeader
= StreamHeaderSize
+ (uint)name
.Length
;
5255 get { return start; }
5256 set { start = value; }
5259 internal uint headerSize()
5261 // Console.WriteLine(name + " stream has headersize of " + sizeOfHeader);
5262 return sizeOfHeader
;
5265 internal void SetSize(uint siz
)
5270 internal uint Size()
5275 internal bool LargeIx()
5280 internal void WriteDetails()
5282 // Console.WriteLine(name + " - size = " + size);
5285 internal uint Add(string str
, bool prependSize
)
5287 Object val
= htable
[str
];
5291 htable
[str
] = index
;
5292 char[] arr
= str
.ToCharArray();
5293 if (prependSize
) CompressNum((uint)arr
.Length
*2+1);
5296 size
= (uint)Seek(0,SeekOrigin
.Current
);
5302 internal uint Add (byte[] str
, bool prependSize
)
5304 Object val
= btable
[str
];
5308 btable
[str
] = index
;
5309 if (prependSize
) CompressNum ((uint) str
.Length
);
5311 size
= (uint) Seek (0, SeekOrigin
.Current
);
5319 internal uint Add(Guid guid
, bool prependSize
)
5321 byte [] b
= guid
.ToByteArray ();
5322 if (prependSize
) CompressNum ((uint) b
.Length
);
5323 Write(guid
.ToByteArray());
5324 size
=(uint)Seek(0,SeekOrigin
.Current
);
5328 internal uint Add(byte[] blob
)
5331 CompressNum((uint)blob
.Length
);
5333 size
= (uint)Seek(0,SeekOrigin
.Current
);
5337 internal uint Add(byte val
, bool prependSize
)
5340 if (prependSize
) CompressNum (1);
5342 size
= (uint)Seek(0,SeekOrigin
.Current
);
5346 internal uint Add(sbyte val
, bool prependSize
)
5349 if (prependSize
) CompressNum (1);
5351 size
= (uint)Seek(0,SeekOrigin
.Current
);
5355 internal uint Add(ushort val
, bool prependSize
)
5358 if (prependSize
) CompressNum (2);
5360 size
= (uint)Seek(0,SeekOrigin
.Current
);
5364 internal uint Add(short val
, bool prependSize
)
5367 if (prependSize
) CompressNum (2);
5369 size
= (uint)Seek(0,SeekOrigin
.Current
);
5373 internal uint Add(uint val
, bool prependSize
)
5376 if (prependSize
) CompressNum (4);
5378 size
= (uint)Seek(0,SeekOrigin
.Current
);
5382 internal uint Add(int val
, bool prependSize
)
5385 if (prependSize
) CompressNum (4);
5387 size
= (uint)Seek(0,SeekOrigin
.Current
);
5391 internal uint Add(ulong val
, bool prependSize
)
5394 if (prependSize
) CompressNum (8);
5396 size
= (uint)Seek(0,SeekOrigin
.Current
);
5400 internal uint Add(long val
, bool prependSize
)
5403 if (prependSize
) CompressNum (8);
5405 size
= (uint)Seek(0,SeekOrigin
.Current
);
5409 internal uint Add(float val
, bool prependSize
)
5412 if (prependSize
) CompressNum (4);
5414 size
= (uint)Seek(0,SeekOrigin
.Current
);
5418 internal uint Add(double val
, bool prependSize
)
5421 if (prependSize
) CompressNum (8);
5423 size
= (uint)Seek(0,SeekOrigin
.Current
);
5427 private void CompressNum(uint val
)
5431 } else if (val
< 0x3FFF) {
5432 byte b1
= (byte)((val
>> 8) | 0x80);
5433 byte b2
= (byte)(val
& FileImage
.iByteMask
[0]);
5437 byte b1
= (byte)((val
>> 24) | 0xC0);
5438 byte b2
= (byte)((val
& FileImage
.iByteMask
[2]) >> 16);
5439 byte b3
= (byte)((val
& FileImage
.iByteMask
[1]) >> 8);;
5440 byte b4
= (byte)(val
& FileImage
.iByteMask
[0]);
5448 private void QuadAlign()
5450 if ((size
% 4) != 0) {
5451 uint pad
= 4 - (size
% 4);
5453 for (int i
=0; i
< pad
; i
++) {
5459 internal void EndStream()
5462 if (size
> maxSmlIxSize
) {
5467 internal void WriteHeader(BinaryWriter output
)
5469 output
.Write(start
);
5474 internal virtual void Write(BinaryWriter output
)
5476 // Console.WriteLine("Writing " + name + " stream at " + output.Seek(0,SeekOrigin.Current) + " = " + start);
5477 MemoryStream str
= (MemoryStream
)BaseStream
;
5478 output
.Write(str
.ToArray());
5483 /**************************************************************************/
5484 class ByteArrayComparer
: IComparer
{
5486 public int Compare (object x
, object y
)
5488 byte [] a
= (byte []) x
;
5489 byte [] b
= (byte []) y
;
5492 if (b
.Length
!= len
)
5495 for (int i
= 0; i
< len
; ++i
)
5502 class ByteArrayHashCodeProvider
: IHashCodeProvider
{
5504 public int GetHashCode (Object key
)
5506 byte [] arr
= (byte []) key
;
5507 int len
= arr
.Length
;
5510 for (int i
= 0; i
< len
; ++i
)
5511 h
= (h
<< 5) - h
+ arr
[i
];