[ilasm] fix the metadata version for v4 assemblies
[mono.git] / mcs / class / PEAPI / Metadata.cs
index 5e016e3435525233daadcac049d329ee22f1503d..a618fe9189e152a3c457419048083559e4dcb270 100644 (file)
@@ -2,6 +2,7 @@ using System;
 using System.IO;
 using System.Collections;
 using System.Text;
+using System.Reflection;
 
 namespace PEAPI {
 
@@ -28,12 +29,13 @@ namespace PEAPI {
        /// <summary>
        /// Attributes for this assembly
        /// </summary>
-       public enum AssemAttr { EnableJITCompileTracking = 0x8000, 
+       public enum AssemAttr { Retargetable = 0x100, EnableJITCompileTracking = 0x8000, 
                DisableJITCompileOptimizer = 0x4000}
 
        /// <summary>
        /// Method call conventions
        /// </summary>
+       [Flags]
        public enum CallConv { Default, Cdecl, Stdcall, Thiscall, 
                Fastcall, Vararg, Instance = 0x20, Generic = 0x10, InstanceExplicit = 0x60 }
 
@@ -45,13 +47,15 @@ namespace PEAPI {
        /// <summary>
        /// Attibutes for a class
        /// </summary>
+       [Flags]
        public enum TypeAttr {Private, Public, NestedPublic, NestedPrivate, 
                NestedFamily, NestedAssembly, NestedFamAndAssem, NestedFamOrAssem, 
                SequentialLayout, ExplicitLayout = 0x10, Interface = 0x20, 
                Abstract = 0x80, PublicAbstract = 0x81, Sealed = 0x100, 
                PublicSealed = 0x101, SpecialName = 0x400, RTSpecialName = 0x800, 
                Import = 0x1000, Serializable = 0x2000, UnicodeClass = 0x10000,
-               AutoClass = 0x20000, HasSecurity = 0x40000, BeforeFieldInit = 0x100000 }
+               AutoClass = 0x20000, HasSecurity = 0x40000, BeforeFieldInit = 0x100000,
+               VisibilityMask = 0x07 }
 
        /// <summary>
        /// Attributes for a field
@@ -68,7 +72,7 @@ namespace PEAPI {
                Family, FamOrAssem, Public, Static = 0x0010, PublicStatic = 0x16, 
                Final = 0x0020, PublicStaticFinal = 0x36, Virtual = 0x0040, 
                PrivateVirtual, PublicVirtual = 0x0046, HideBySig = 0x0080, 
-               NewSlot = 0x0100, Abstract = 0x0400, SpecialName = 0x0800,
+               NewSlot = 0x0100, Strict = 0x200, Abstract = 0x0400, SpecialName = 0x0800,
                RTSpecialName = 0x1000, SpecialRTSpecialName = 0x1800, 
                HasSecurity = 0x4000, RequireSecObject = 0x8000}
 
@@ -76,8 +80,11 @@ namespace PEAPI {
        /// Attributes for .pinvokeimpl method declarations
        /// </summary>
        public enum PInvokeAttr { nomangle = 1, ansi = 2, unicode = 4, autochar = 6,
+               bestfit_on = 0x0010, bestfit_off = 0x0020, bestfit_mask = 0x0030,
                lasterr = 0x0040, winapi = 0x0100, cdecl = 0x0200,
-               stdcall = 0x0300, thiscall = 0x0400, fastcall = 0x0500 }
+               stdcall = 0x0300, thiscall = 0x0400, fastcall = 0x0500,
+               charmaperror_on = 0x1000, charmaperror_off = 0x2000
+       }
 
        /// <summary>
        /// Implementation attributes for a method
@@ -115,7 +122,7 @@ namespace PEAPI {
                add_ovf_un, mul_ovf, mul_ovf_un, sub_ovf, sub_ovf_un, endfinally, 
                stind_i = 0xDF, conv_u, arglist = 0xFE00, ceq, cgt, cgt_un, clt, clt_un, 
                localloc = 0xFE0F, endfilter = 0xFE11, volatile_ = 0xFE13, tail_, 
-               cpblk = 0xFE17, initblk, rethrow = 0xFE1A, refanytype = 0xFE1D}
+               cpblk = 0xFE17, initblk, rethrow = 0xFE1A, refanytype = 0xFE1D, readonly_ = 0xFE1E }
 
        /// <summary>
        /// CIL instructions requiring an integer parameter
@@ -142,8 +149,8 @@ namespace PEAPI {
        public enum TypeOp {cpobj = 0x70, ldobj, castclass = 0x74, isinst, 
                unbox = 0x79, stobj = 0x81, box = 0x8C, newarr, 
                ldelema = 0x8F, refanyval = 0xC2, mkrefany = 0xC6, 
-               ldtoken = 0xD0, initobj = 0xFE15, sizeOf = 0xFE1C,
-               ldelem = 0xA3, stelem = 0xA4, unbox_any }
+               ldtoken = 0xD0, initobj = 0xFE15, constrained = 0xFE16, 
+               sizeOf = 0xFE1C, ldelem = 0xA3, stelem = 0xA4, unbox_any }
 
        /// <summary>
        /// CIL branch instructions
@@ -183,6 +190,23 @@ namespace PEAPI {
 
        public enum ValueClass { ValueType, Enum }
 
+       public enum GenParamType : byte { 
+               Var = 0x13, MVar = 0x1E 
+       }
+
+       [Flags]
+       public enum GenericParamAttributes : ushort {
+               VarianceMask  = 0x0003,
+               NonVariant    = 0x0000,
+               Covariant     = 0x0001,
+               Contravariant = 0x0002,
+
+               SpecialConstraintMask = 0x001c,
+               ReferenceTypeConstraint = 0x0004,
+               NotNullableValueTypeConstraint = 0x0008,
+               DefaultConstructorConstrait = 0x0010
+       }
+
        /* Taken from Mono.Cecil */
        public enum SecurityAction : short {
                Request = 1,
@@ -218,6 +242,8 @@ namespace PEAPI {
                protected bool done = false;
                protected MDTable tabIx;
                protected bool sortTable = false;
+               //Temporary hack.. 
+               private bool has_custom_attrs = false;
 
                internal MetaDataElement() { }
 
@@ -226,10 +252,15 @@ namespace PEAPI {
                                return row;
                        }
                        set {
-                               if (row == 0) row = value;
+                               row = value;
                        }
                }
 
+               public bool HasCustomAttr {
+                       get { return has_custom_attrs; }
+                       set { has_custom_attrs = value; }
+               }
+
                internal virtual uint GetCodedIx(CIx code) { return 0; }
 
                /// <summary>
@@ -440,9 +471,14 @@ namespace PEAPI {
 
                internal sealed override void BuildTables(MetaData md) 
                {
+                       md.AddToTable(MDTable.CustomAttribute, this);
+                       if (byteVal == null) {
+                               valIx = 0;
+                               return;
+                       }
+
                        BinaryWriter bw = new BinaryWriter(new MemoryStream());
                        bw.Write(byteVal);
-                       md.AddToTable(MDTable.CustomAttribute, this);
                        MemoryStream str = (MemoryStream)bw.BaseStream;
                        valIx = md.AddToBlobHeap(str.ToArray());
                }
@@ -466,19 +502,17 @@ namespace PEAPI {
        /// Descriptor for security permissions for a class or a method
        /// </summary>
 
-       public class DeclSecurity : MetaDataElement {
+       public abstract class BaseDeclSecurity : MetaDataElement {
 
                ushort action;
                MetaDataElement parent;
                uint permissionIx;
-               byte [] byteVal;
 
-               internal DeclSecurity(MetaDataElement paren, ushort act, byte [] val)        
+               internal BaseDeclSecurity(MetaDataElement paren, ushort act)
                {
                        parent = paren;
                        action = act;
                        tabIx = MDTable.DeclSecurity;
-                       byteVal = val;
                }
 
                internal override uint SortKey() 
@@ -495,15 +529,18 @@ namespace PEAPI {
                internal sealed override void BuildTables(MetaData md) 
                {
                        if (done) return;
+
                        BinaryWriter bw = new BinaryWriter (new MemoryStream ());
-                       bw.Write (byteVal);
                        md.AddToTable (MDTable.DeclSecurity, this);
                        MemoryStream str = (MemoryStream)bw.BaseStream;
+                       WriteSig (bw);
                        permissionIx = md.AddToBlobHeap(str.ToArray());
 
                        done = true;
                }
 
+               internal abstract void WriteSig (BinaryWriter bw);
+
                internal sealed override void Write(FileImage output) 
                {
                        output.Write(action);
@@ -513,6 +550,154 @@ namespace PEAPI {
 
        }
 
+       public class DeclSecurity : BaseDeclSecurity {
+
+               byte [] byteVal;
+
+               internal DeclSecurity(MetaDataElement paren, ushort act, byte [] val)        
+                       : base (paren, act)
+               {
+                       byteVal = val;
+               }
+
+               internal override void WriteSig (BinaryWriter bw)
+               {
+                       bw.Write (byteVal);
+               }
+
+       }
+
+       public class DeclSecurity_20 : BaseDeclSecurity {
+
+               PermissionSet ps;
+
+               internal DeclSecurity_20 (MetaDataElement paren, ushort act, PermissionSet ps)
+                       : base (paren, act)
+               {
+                        this.ps = ps;
+               }
+
+               internal override void WriteSig (BinaryWriter bw)
+               {
+                       ps.Write (bw);
+               }
+       }
+
+       public class PermissionMember {
+
+               MemberTypes member_type;
+               PEAPI.Type type;
+               string name;
+               object value;
+
+               public PermissionMember (MemberTypes member_type, PEAPI.Type type, string name, object value)
+               {
+                       this.member_type = member_type;
+                       this.type = type;
+                       this.name = name;
+                       this.value = value;
+               }
+
+               public void Write (BinaryWriter bw)
+               {
+                       byte [] b;
+
+                       if (member_type == MemberTypes.Field)
+                               bw.Write ((byte) 0x53);
+                       else
+                               //Property
+                               bw.Write ((byte) 0x54);
+
+                       if (type is PrimitiveType) {
+                               bw.Write (type.GetTypeIndex ());
+                       } else {
+                               //must be enum
+                               bw.Write ((byte) 0x55); //ENUM
+
+                               b = Encoding.UTF8.GetBytes (((ClassRef) type).TypeName ());
+                               MetaData.CompressNum ((uint) b.Length, (MemoryStream) bw.BaseStream);
+                               bw.Write (b);
+                       }
+                       
+                       b = Encoding.UTF8.GetBytes (name);
+                       MetaData.CompressNum ((uint) b.Length, (MemoryStream) bw.BaseStream);
+                       bw.Write (b);
+
+                       ((Constant) value).Write (bw);
+               }
+
+       }
+
+       public class Permission
+       {
+               PEAPI.Type type;
+
+               //PermissionMembers
+               ArrayList members;
+               string name;
+
+               public Permission (PEAPI.Type type, string name)
+               {
+                       this.type = type;
+                       this.name = name;
+               }
+
+               public void AddMember (PEAPI.PermissionMember member)
+               {
+                       if (members == null)
+                               members = new ArrayList ();
+
+                       members.Add (member);
+               }
+
+               public void Write (BinaryWriter bw)
+               {
+                       byte [] b = Encoding.UTF8.GetBytes (name);
+                       MetaData.CompressNum ((uint) b.Length, (MemoryStream) bw.BaseStream);
+                       bw.Write (b);
+
+                       BinaryWriter perm_writer = new BinaryWriter (new MemoryStream (), Encoding.Unicode);
+                       MemoryStream str = (MemoryStream) perm_writer.BaseStream;
+
+                       MetaData.CompressNum ((uint) members.Count, str);//number of params
+                       foreach (PermissionMember member in members)
+                               member.Write (perm_writer);
+
+                       bw.Write ((byte) str.Length); //(optional) parameters length
+                       bw.Write (str.ToArray ());
+               }
+       }
+
+       public class PermissionSet 
+       {
+               PEAPI.SecurityAction sec_action;
+               ArrayList permissions;
+               PEAPI.PermissionSet ps;
+
+               public PermissionSet (PEAPI.SecurityAction sec_action)
+               {
+                       this.sec_action = sec_action;
+               }
+
+               public void AddPermission (PEAPI.Permission perm)
+               {
+                       if (permissions == null)
+                               permissions = new ArrayList ();
+
+                       permissions.Add (perm);
+               }
+
+               public void Write (BinaryWriter bw)
+               {
+                       bw.Write ((byte) 0x2e);
+                       MetaData.CompressNum ((uint) permissions.Count, (MemoryStream) bw.BaseStream);
+
+                       foreach (Permission perm in permissions)
+                               perm.Write (bw);
+               }
+
+       }
+
        /**************************************************************************/  
        /// <summary>
        /// Descriptor for layout information for a field
@@ -738,27 +923,29 @@ namespace PEAPI {
 
                MetaDataElement owner;
                MetaData metadata;
-               string name;
+               public string name;
                uint nameIx;
                short index;
+               GenericParamAttributes attr;
 
                internal GenericParameter (ClassDef owner, MetaData metadata,
-                               short index, string name) : this (owner, metadata, index, name, true)
+                               short index, string name, GenericParamAttributes attr) : this (owner, metadata, index, name, attr, true)
                {
                }
 
                internal GenericParameter (MethodDef owner, MetaData metadata,
-                               short index, string name) : this (owner, metadata, index, name, true)
+                               short index, string name, GenericParamAttributes attr) : this (owner, metadata, index, name, attr, true)
                {
                }
 
                private GenericParameter (MetaDataElement owner, MetaData metadata,
-                               short index, string name, bool nadda) {
+                               short index, string name, GenericParamAttributes attr, bool nadda) {
                        this.owner = owner;
                        this.metadata = metadata;
                        this.index = index;
                        tabIx = MDTable.GenericParam;
                        this.name = name;
+                       this.attr = attr;
                }
 
                internal override uint SortKey() 
@@ -767,6 +954,11 @@ namespace PEAPI {
                                | owner.GetCodedIx(CIx.TypeOrMethodDef);
                }
 
+               internal override uint SortKey2 ()
+               {
+                       return (uint) index;
+               }
+
                public void AddConstraint  (Type constraint) 
                {
                        metadata.AddToTable (MDTable.GenericParamConstraint,
@@ -777,8 +969,7 @@ namespace PEAPI {
                {
                        return (uint) (4 +
                                        md.CodedIndexSize(CIx.TypeOrMethodDef) + 
-                                       4 +
-                                       md.TableIndexSize(MDTable.TypeDef));
+                                       md.StringsIndexSize ());
                }
 
                internal sealed override void BuildTables(MetaData md) 
@@ -791,12 +982,18 @@ namespace PEAPI {
                internal sealed override void Write(FileImage output) 
                {
                        output.Write ((short) index);
-                       output.Write ((short) 0);
+                       output.Write ((short) attr);
                        output.WriteCodedIndex(CIx.TypeOrMethodDef, owner);
-                       output.Write ((uint) nameIx);
-                       output.WriteIndex(MDTable.TypeDef,owner.Row);
+                       output.StringsIndex (nameIx);
                }
 
+               internal sealed override uint GetCodedIx(CIx code) 
+               {
+                       switch (code) {
+                               case (CIx.HasCustomAttr) : return 19; 
+                       }
+                       return 0;
+               }
 
        }
 
@@ -812,6 +1009,11 @@ namespace PEAPI {
                        tabIx = MDTable.GenericParamConstraint;
                }
 
+               internal override uint SortKey() 
+               {
+                       return param.Row;
+               }
+
                internal sealed override uint Size(MetaData md) 
                {
                        return (uint) (md.TableIndexSize(MDTable.GenericParam) +
@@ -826,19 +1028,29 @@ namespace PEAPI {
 
        }
 
-       internal class MethodSpec : MetaDataElement {
+       internal class MethodSpec : Method {
 
                Method meth;
                GenericMethodSig g_sig;
                uint sidx;
 
-               internal MethodSpec (Method meth, GenericMethodSig g_sig) 
+               internal MethodSpec (Method meth, GenericMethodSig g_sig) : base ("")
                {
                        this.meth = meth;
                        this.g_sig = g_sig;
                        tabIx = MDTable.MethodSpec;
                }
 
+               internal override uint GetSigIx (MetaData md)
+               {
+                       throw new Exception ("Should not be used.");
+               }
+
+               public override void AddCallConv (CallConv cconv)
+               {
+                       throw new Exception ("Should not be used.");
+               }
+               
                internal sealed override void BuildTables (MetaData md) 
                {
                        if (done) return;
@@ -857,6 +1069,11 @@ namespace PEAPI {
                        output.WriteCodedIndex (CIx.MethodDefOrRef, meth);
                        output.BlobIndex (sidx);
                }
+
+               internal sealed override void TypeSig (MemoryStream sig)
+               {
+                       throw new Exception ("Should not be used.");
+               }
        }
 
        /**************************************************************************/
@@ -962,11 +1179,11 @@ namespace PEAPI {
                        nameIx = md.AddToStringsHeap(mrName);
                        if (resourceBytes != null) {
                                if (rRef != null)
-                                       throw new Exception("ERROR:  Manifest Resource has byte value and file reference");
+                                       throw new PEFileException ("Manifest Resource has byte value and file reference");
                                fileOffset = md.AddResource(resourceBytes);
                        } else {
                                if (rRef == null)
-                                       throw new Exception("ERROR:  Manifest Resource has no implementation or value");
+                                       throw new PEFileException ("Manifest Resource has no implementation or value");
                                rRef.BuildTables (md);
                        }
 
@@ -1123,6 +1340,10 @@ namespace PEAPI {
                        tabIx = MDTable.Param;
                }
 
+               public bool HasMarshalInfo {
+                       get { return marshalInfo != null; }
+               }
+
                /// <summary>
                /// Add a default value to this parameter
                /// </summary>
@@ -1322,6 +1543,12 @@ namespace PEAPI {
                        nameIx = nIx;
                }
 
+               internal Class (byte typeIndex) : base (typeIndex)
+               {
+                       nameSpace = "Should not be used";
+                       name = "Should not be used";
+               }
+
                internal virtual uint TypeDefOrRefToken() { return 0; }
 
                internal virtual void MakeValueClass(ValueClass vClass) 
@@ -1382,9 +1609,7 @@ namespace PEAPI {
                internal void SetSuper(Class sClass) 
                {
                        superType = sClass;
-                       if (sClass is ClassRef)
-                               typeIndex = superType.GetTypeIndex();
-                       else
+                       if (! (sClass is GenericTypeInst))
                                typeIndexChecked = false;
                }
 
@@ -1426,7 +1651,15 @@ namespace PEAPI {
                /// </summary>
                public GenericParameter AddGenericParameter (short index, string name) 
                {
-                       GenericParameter gp = new GenericParameter (this, metaData, index, name);
+                       return AddGenericParameter (index, name, 0);
+               }
+
+               /// <summary>
+               ///  Add a named generic type parameter with attributes
+               /// </summary>
+               public GenericParameter AddGenericParameter (short index, string name, GenericParamAttributes attr)
+               {
+                       GenericParameter gp = new GenericParameter (this, metaData, index, name, attr);
                        metaData.AddToTable (MDTable.GenericParam, gp);
                        return gp;
                }
@@ -1471,9 +1704,14 @@ namespace PEAPI {
                /// <param name="pars">parameters</param>
                /// <returns>a descriptor for this new method</returns>
                public MethodDef AddMethod(string name, Type retType, Param[] pars) 
+               {
+                       return AddMethod (name, new Param (ParamAttr.Default, "", retType), pars);
+               }
+
+               public MethodDef AddMethod (string name, Param ret_param, Param [] pars) 
                {
                        // Console.WriteLine("Adding method " + name + " to class " + this.name);
-                       MethodDef meth = new MethodDef(metaData,name,retType, pars);
+                       MethodDef meth = new MethodDef(metaData,name, ret_param, pars);
                        methods.Add(meth);
                        return meth;
                }
@@ -1488,9 +1726,9 @@ namespace PEAPI {
                /// <param name="pars">parameters</param>
                /// <returns>a descriptor for this new method</returns>
                public MethodDef AddMethod(MethAttr mAtts, ImplAttr iAtts, string name, 
-                               Type retType, Param[] pars) {
+                               Param ret_param, Param [] pars) {
                        // Console.WriteLine("Adding method " + name + " to class " + this.name);
-                       MethodDef meth = new MethodDef(metaData,mAtts,iAtts,name,retType,pars);
+                       MethodDef meth = new MethodDef (metaData, mAtts, iAtts, name, ret_param, pars);
                        methods.Add(meth);
                        return meth;
                }
@@ -1621,7 +1859,7 @@ namespace PEAPI {
                internal void CheckTypeIndex() 
                {
                        if (typeIndexChecked) return;
-                       if (!(superType is ClassRef)
+                       if (superType is ClassDef
                                ((ClassDef)superType).CheckTypeIndex();
                        typeIndex = superType.GetTypeIndex();
                        typeIndexChecked = true;
@@ -1739,7 +1977,20 @@ namespace PEAPI {
                /// <returns>a descriptor for this method</returns>
                public MethodRef AddMethod(string name, Type retType, Type[] pars) 
                {
-                       MethodRef meth = new MethodRef(this,name,retType,pars,false,null);
+                       return AddMethod (name, retType, pars, 0);
+               }
+               
+               /// <summary>
+               /// Add a method to this class
+               /// </summary>
+               /// <param name="name">method name</param>
+               /// <param name="retType">return type</param>
+               /// <param name="pars">parameter types</param>
+               /// <param name="gen_param_count">num of generic parameters</param>
+               /// <returns>a descriptor for this method</returns>
+               public MethodRef AddMethod (string name, Type retType, Type[] pars, int gen_param_count) 
+               {
+                       MethodRef meth = new MethodRef (this, name, retType, pars, false, null, gen_param_count);
                        metaData.AddToTable(MDTable.MemberRef,meth);
                        return meth;
                }
@@ -1754,7 +2005,7 @@ namespace PEAPI {
                public MethodRef AddVarArgMethod(string name, Type retType, 
                                Type[] pars, Type[] optPars) 
                {
-                       MethodRef meth = new MethodRef(this,name,retType,pars,true,optPars);
+                       MethodRef meth = new MethodRef(this,name,retType,pars,true,optPars, 0);
                        metaData.AddToTable(MDTable.MemberRef,meth);
                        return meth;
                }
@@ -1909,53 +2160,98 @@ namespace PEAPI {
 
        }
 
-       public class MVar : Type {
+       public class GenParam : Class {
 
                private int index;
+               private string param_name;
+               private uint sigIx = 0;
 
-               public MVar (int index) : base (0x1E
+               public GenParam (int index, string name, GenParamType ptype) : base ((byte) ptype
                {
                        this.index = index;
+                       this.param_name = name;
                        tabIx = MDTable.TypeSpec;
                }
 
-               internal sealed override void TypeSig(MemoryStream str) 
-               {
-                       str.WriteByte(typeIndex);
-                       MetaData.CompressNum ((uint) index, str);
+               public int Index {
+                       get { return index; }
+                       set { index = value; }
                }
-       }
 
-       public class GenericTypeSpec : Type {
-
-               private int index;
+               public string Name {
+                       get { return param_name; }
+                       set { param_name = value; }
+               }
 
-               public GenericTypeSpec (int index) : base (0x13) 
+               public GenParamType Type {
+                       get { return (GenParamType) GetTypeIndex (); }
+               }
+               
+               internal sealed override void BuildTables (MetaData md)
                {
-                       this.index = index;
-                       tabIx = MDTable.TypeSpec;
+                       if (done)
+                               return;
+                       MemoryStream str = new MemoryStream ();
+                       TypeSig (str);
+                       sigIx = md.AddToBlobHeap (str.ToArray ());
+
+                       done = true;
                }
 
                internal sealed override void TypeSig(MemoryStream str) 
                {
+                       if (index < 0)
+                               throw new PEFileException (String.Format ("Unresolved {0} - {1}", (GenParamType) GetTypeIndex (), param_name));
                        str.WriteByte(typeIndex);
                        MetaData.CompressNum ((uint) index, str);
                }
+               
+               internal override uint Size(MetaData md) 
+               {
+                       return md.BlobIndexSize();
+               }
+
+               internal sealed override void Write (FileImage output)
+               {
+                       output.BlobIndex (sigIx);       
+               }
+
+               internal sealed override uint GetCodedIx(CIx code) 
+               {
+                       switch (code) {
+                               case (CIx.TypeDefOrRef) : return 2; 
+                               case (CIx.HasCustomAttr) : return 13; 
+                               case (CIx.MemberRefParent) : return 4; 
+                       }
+                       return 0;
+               }
        }
 
-       public class GenericTypeInst : Type {
+       public class GenericTypeInst : Class {
 
                private Type gen_type;
                private Type[] gen_param;
+               bool inTable = false;
+               uint sigIx = 0;
 
-               public GenericTypeInst (Type gen_type, Type[] gen_param) : base (0x15)
+               public GenericTypeInst (Type gen_type, Type[] gen_param) 
+                       : base ((byte) PrimitiveType.GenericInst.GetTypeIndex ())
                {
-                       typeIndex = 0x15;
                        this.gen_type = gen_type;
                        this.gen_param = gen_param;
                        tabIx = MDTable.TypeSpec;
                }
 
+               internal override MetaDataElement GetTypeSpec (MetaData md)
+               {
+                       if (!inTable) {
+                               md.AddToTable (MDTable.TypeSpec, this);
+                               inTable = true;
+                       }
+
+                       return this;
+               }
+
                internal sealed override void TypeSig(MemoryStream str) 
                {
                        str.WriteByte(typeIndex);
@@ -1964,20 +2260,54 @@ namespace PEAPI {
                        foreach (Type param in gen_param)
                                param.TypeSig (str);
                }
+
+               internal sealed override void BuildTables (MetaData md)
+               {
+                       if (done)
+                               return;
+                       MemoryStream str = new MemoryStream ();
+                       TypeSig (str);
+                       sigIx = md.AddToBlobHeap (str.ToArray ());
+
+                       done = true;
+               }
+
+               internal sealed override uint Size (MetaData md)
+               {
+                       return md.BlobIndexSize ();
+               }
+
+               internal sealed override void Write (FileImage output)
+               {
+                       output.BlobIndex (sigIx);       
+               }
+
+               internal sealed override uint GetCodedIx (CIx code)
+               {
+                       switch (code) {
+                               case (CIx.TypeDefOrRef): return 2;
+                               case (CIx.MemberRefParent): return 4;
+                               case (CIx.HasCustomAttr): return 13;
+                       }
+                       return 0;
+               }
        }
 
        public class GenericMethodSig {
 
                private Type[] gen_param;
+               private bool done;
+               private uint sigIx = 0;
 
                public GenericMethodSig (Type[] gen_param)
                {
                        this.gen_param = gen_param;
+                       done = false;
                }
 
                internal void TypeSig (MemoryStream str)
                {
-                       MetaData.CompressNum ((uint) gen_param.Length, str); // THIS IS NOT RIGHT, but works
+                       str.WriteByte (0x0A); /* GENERIC_INST */
                        MetaData.CompressNum ((uint) gen_param.Length, str);
                        foreach (Type param in gen_param)
                                param.TypeSig (str);
@@ -1985,9 +2315,14 @@ namespace PEAPI {
 
                internal uint GetSigIx (MetaData md)
                {
+                       if (done)
+                               return sigIx;
+
                        MemoryStream sig = new MemoryStream();
                        TypeSig (sig);
-                       return md.AddToBlobHeap (sig.ToArray());
+                       sigIx = md.AddToBlobHeap (sig.ToArray());
+                       done = true;
+                       return sigIx;
                }
        }
 
@@ -2132,16 +2467,13 @@ namespace PEAPI {
                /// <param name="elementType">the type of the elements</param>
                /// <param name="dimensions">the number of dimensions</param>
                /// <param name="loBounds">lower bounds of dimensions</param>
-               /// <param name="upBounds">upper bounds of dimensions</param>
+               /// <param name="sizes">sizes for the dimensions</param>
                public BoundArray(Type elementType, uint dimensions, int[] loBounds, 
-                               int[] upBounds) : base (elementType,0x14) 
+                               int[] sizes) : base (elementType,0x14) 
                {
                        numDims = dimensions;
                        lowerBounds = loBounds;
-                       sizes = new int[loBounds.Length];
-                       for (int i=0; i < loBounds.Length; i++) {
-                               sizes[i] = upBounds[i] - loBounds[i] + 1;
-                       }
+                       this.sizes = sizes;
                }
 
                /// <summary>
@@ -2185,11 +2517,54 @@ namespace PEAPI {
                        if ((lowerBounds != null) && (lowerBounds.Length > 0)) {
                                MetaData.CompressNum((uint)lowerBounds.Length,str);
                                for (int i=0; i < lowerBounds.Length; i++) {
-                                       MetaData.CompressNum((uint)lowerBounds[i],str);
+                                       CompressSignedNum (lowerBounds[i],str);
                                }
                        } else str.WriteByte(0);
                }
+               private void CompressSignedNum (int val, MemoryStream str)
+               {
+                       uint uval = (uint) val;
+                       byte sign = 0;
+                       if (val < 0) {
+                               val = -val;
+                               sign = 1;
+                       }
+
+                       /* Map the signed number to an unsigned number in two ways.
+
+                            fval: left-rotated 2's complement representation
+                            sval: map the signed number to unsigned as follows: 0 -> 0, -1 -> 1, 1 -> 2, -2 -> 3, 2 -> 4, ....
+                                  the mapping is: x -> 2*|x| - signbit(x)
+                       */
+                       uint fval = (uval << 1) | sign;
+                       int sval = (val  << 1) - sign;
+
+                       /* An overly clever transformation: 
+
+                          a. sval is used to determine the number of bytes in the compressed representation.
+                          b. fval is truncated to the appropriate number of bits and output using the 
+                             normal unsigned-int compressor.
 
+                          However, or certain values, the truncated fval doesn't carry enough information to round trip.
+
+                               (fval & 0x3FFF) <= 0x7F => compressor emits 1 byte, not 2 => there is aliasing of values
+
+                          So, we use full 4 bytes to encode such values.
+
+                          LAMESPEC: The Microsoft implementation doesn't appear to handle this subtle case.
+                                    e.g., it ends up encoding -8192 as the byte 0x01, which decodes to -64
+                       */
+                       if (sval <= 0x7F)
+                               MetaData.CompressNum (fval & 0x7F, str);
+                       else if (sval <= 0x3FFF && (fval & 0x3FFF) > 0x7F)
+                               MetaData.CompressNum (fval & 0x3FFF, str);
+                       else if (sval <= 0x1FFFFFFF && (fval & 0x1FFFFFFF) > 0x3FFF)
+                               MetaData.CompressNum (fval & 0x1FFFFFFF, str);
+                       else
+                               /* FIXME: number cannot be represented.  Report a warning.  */
+                               // throw new Exception ("cannot represent signed value" + -val);
+                               MetaData.CompressNum (fval, str);
+               }
        }
 
        #endregion
@@ -2307,7 +2682,7 @@ namespace PEAPI {
        /// <summary>
        /// Descriptor for THIS module
        /// </summary>
-       public class Module : ResolutionScope {
+       public class Module : ResolutionScope, IExternRef {
 
                Guid mvid;
                uint mvidIx = 0;
@@ -2323,6 +2698,21 @@ namespace PEAPI {
                        get { return mvid; }
                }
 
+               public ClassRef AddClass(string nsName, string name) 
+               {
+                       ClassRef aClass = new ClassRef (nsName, name, metaData);
+                       metaData.AddToTable (MDTable.TypeRef, aClass);
+                       aClass.SetParent (this);
+                       return aClass;
+               }
+
+               public ClassRef AddValueClass(string nsName, string name) 
+               {
+                       ClassRef aClass = AddClass (nsName, name);
+                       aClass.MakeValueClass (ValueClass.ValueType);
+                       return aClass;
+               }
+
                internal sealed override uint Size(MetaData md) 
                {
                        return 2 + md.StringsIndexSize() + 3 * md.GUIDIndexSize();
@@ -2433,7 +2823,7 @@ namespace PEAPI {
                /// <returns>a descriptor for this method in anther module</returns>
                public MethodRef AddMethod(string name, Type retType, Type[] pars) 
                {
-                       MethodRef meth = new MethodRef(this,name,retType,pars,false,null);
+                       MethodRef meth = new MethodRef(this,name,retType,pars,false,null, 0);
                        metaData.AddToTable(MDTable.MemberRef,meth);
                        return meth;
                }
@@ -2448,7 +2838,7 @@ namespace PEAPI {
                /// <returns>a descriptor for this method</returns>
                public MethodRef AddVarArgMethod(string name, Type retType, 
                                Type[] pars, Type[] optPars) {
-                       MethodRef meth = new MethodRef(this,name,retType,pars,true,optPars);
+                       MethodRef meth = new MethodRef(this,name,retType,pars,true,optPars, 0);
                        metaData.AddToTable(MDTable.MemberRef,meth);
                        return meth;
                }
@@ -2726,27 +3116,27 @@ namespace PEAPI {
        }
 
        public class UIntConst : Constant {
-               long val;
+               ulong val;
 
-               public UIntConst(sbyte val) 
+               public UIntConst(byte val) 
                {
                        this.val = val;
                        size = 1;
                        type = PrimitiveType.UInt8;
                }
-               public UIntConst(short val) 
+               public UIntConst(ushort val) 
                {
                        this.val = val;
                        size = 2;
                        type = PrimitiveType.UInt16;
                }
-               public UIntConst(int val) 
+               public UIntConst(uint val) 
                {
                        this.val = val;
                        size = 4;
                        type = PrimitiveType.UInt32;
                }
-               public UIntConst(long val) 
+               public UIntConst(ulong val) 
                {
                        this.val = val;
                        size = 8;
@@ -2757,9 +3147,9 @@ namespace PEAPI {
                {
                        if (!addedToBlobHeap) {
                                switch (size) {
-                                       case (1) : blobIndex = md.AddToBlobHeap((sbyte)val); break;
-                                       case (2) : blobIndex = md.AddToBlobHeap((short)val); break;
-                                       case (4) : blobIndex = md.AddToBlobHeap((int)val); break;
+                                       case (1) : blobIndex = md.AddToBlobHeap((byte)val); break;
+                                       case (2) : blobIndex = md.AddToBlobHeap((ushort)val); break;
+                                       case (4) : blobIndex = md.AddToBlobHeap((uint)val); break;
                                        default : blobIndex = md.AddToBlobHeap(val); break;
                                }
                                addedToBlobHeap = true;
@@ -2770,9 +3160,9 @@ namespace PEAPI {
                internal sealed override void Write(BinaryWriter bw) 
                {
                        switch (size) {
-                               case (1) : bw.Write((sbyte)val); break;
-                               case (2) : bw.Write((short)val); break;
-                               case (4) : bw.Write((int)val); break;
+                               case (1) : bw.Write((byte)val); break;
+                               case (2) : bw.Write((ushort)val); break;
+                               case (4) : bw.Write((uint)val); break;
                                default : bw.Write(val); break;
                        }
                }
@@ -3097,6 +3487,7 @@ namespace PEAPI {
        public class Property : Feature {
 
                private static readonly byte PropertyTag = 0x8;
+               private bool instance;
                MethodDef getterMeth;
                ConstantElem constVal;
                uint typeBlobIx = 0;
@@ -3149,12 +3540,20 @@ namespace PEAPI {
                        this.constVal = new ConstantElem(this,constVal);
                }
 
+               public void SetInstance (bool isInstance)
+               {
+                       this.instance = isInstance;
+               }
+
                internal sealed override void BuildTables(MetaData md) 
                {
                        if (done) return;
                        nameIx = md.AddToStringsHeap(name);
                        MemoryStream sig = new MemoryStream();
-                       sig.WriteByte(PropertyTag);
+                       byte tag = PropertyTag;
+                       if (instance)
+                               tag |= 0x20;
+                       sig.WriteByte(tag);
                        MetaData.CompressNum(numPars,sig);
                        returnType.TypeSig(sig);
                        for (int i=0; i < numPars; i++) {
@@ -3401,37 +3800,12 @@ namespace PEAPI {
 
        public abstract class Method : Member {
 
-               protected CallConv callConv = CallConv.Default;
-               protected Type retType;
-
-               internal Method(string methName, Type rType) : base(methName)
-               {
-                       retType = rType;
-               }
-
-               /// <summary>
-               /// Add calling conventions to this method descriptor
-               /// </summary>
-               /// <param name="cconv"></param>
-               public void AddCallConv(CallConv cconv) 
-               {
-                       callConv |= cconv;
-               }
+               internal Method (string methName) : base (methName)
+               {}
 
+               public abstract void AddCallConv(CallConv cconv);
                internal abstract void TypeSig(MemoryStream sig);
-
-               internal uint GetSigIx(MetaData md) 
-               {
-                       MemoryStream sig = new MemoryStream();
-                       TypeSig(sig);
-                       return md.AddToBlobHeap(sig.ToArray());
-               }
-
-               internal Type GetRetType() 
-               {
-                       return retType;
-               }
-
+               internal abstract uint GetSigIx(MetaData md);
        }
 
        /**************************************************************************/  
@@ -3446,6 +3820,8 @@ namespace PEAPI {
                //private static readonly uint UnmanagedExport = 0x0008;
                // private static readonly byte LocalSigByte = 0x7;
                uint parIx = 0, textOffset = 0;
+               private CallConv callConv = CallConv.Default;
+               private int gen_param_count;
 
                MetaData metaData;
                CILInstructions code;
@@ -3461,23 +3837,22 @@ namespace PEAPI {
                ImplMap pinvokeImpl;
                Param ret_param;
 
-
-               internal MethodDef(MetaData md, string name, Type retType, Param[] pars) : base(name,retType) 
+               internal MethodDef (MetaData md, string name, Param ret_param, Param [] pars)
+                       : this (md, 0, 0, name, ret_param, pars)
                {
-                       metaData = md;
-                       parList = pars;
-                       if (parList != null) numPars = parList.Length;
-                       tabIx = MDTable.Method;
                }
 
-               internal MethodDef(MetaData md, MethAttr mAttrSet, ImplAttr iAttrSet, string name, Type retType, Param[] pars) : base(name,retType) 
+               internal MethodDef (MetaData md, MethAttr mAttrSet, ImplAttr iAttrSet, string name, 
+                               Param ret_param, Param [] pars) 
+                       : base (name)
                {
-                       metaData = md;
-                       parList = pars;
-                       if (parList != null) numPars = parList.Length;
-                       // Console.WriteLine("Creating method " + name + " with " + numPars + " parameters");
                        methFlags = (ushort)mAttrSet;
                        implFlags = (ushort)iAttrSet;
+                       this.ret_param = ret_param;
+                       metaData = md;
+                       parList = pars;
+                       if (parList != null) 
+                               numPars = parList.Length;
                        tabIx = MDTable.Method;
                }
 
@@ -3486,6 +3861,18 @@ namespace PEAPI {
                        return parList;
                }
 
+               internal override uint GetSigIx(MetaData md)
+               {
+                       MemoryStream sig = new MemoryStream();
+                       TypeSig(sig);
+                       return md.AddToBlobHeap(sig.ToArray());
+               }
+
+               public override void AddCallConv(CallConv cconv)
+               {
+                       callConv |= cconv;
+               }
+               
                /// <summary>
                /// Add some attributes to this method descriptor
                /// </summary>
@@ -3515,8 +3902,17 @@ namespace PEAPI {
                /// </summary>
                public GenericParameter AddGenericParameter (short index, string name) 
                {
-                       GenericParameter gp = new GenericParameter (this, metaData, index, name);
+                       return AddGenericParameter (index, name, 0);
+               }
+
+               /// <summary>
+               ///  Add a named generic type parameter with attributes
+               /// </summary>
+               public GenericParameter AddGenericParameter (short index, string name, GenericParamAttributes attr) 
+               {
+                       GenericParameter gp = new GenericParameter (this, metaData, index, name, attr);
                        metaData.AddToTable (MDTable.GenericParam, gp);
+                       gen_param_count ++;
                        return gp;
                }
 
@@ -3543,7 +3939,6 @@ namespace PEAPI {
                /* Add Marshal info for return type */
                public void AddRetTypeMarshallInfo (NativeType marshallType) 
                {
-                       ret_param = new Param (ParamAttr.HasFieldMarshal, "", retType);
                        ret_param.AddMarshallInfo (marshallType);
                }
 
@@ -3578,7 +3973,7 @@ namespace PEAPI {
                        for (int i=0; i < numPars; i++) {
                                pars[i] = parList[i].GetParType();
                        }
-                       varArgSig = new MethodRef(this,name,retType,pars,true,optPars);
+                       varArgSig = new MethodRef (this, name, ret_param.GetParType (), pars, true, optPars, 0);
 
                        if (varArgSigList == null)
                                varArgSigList = new ArrayList ();
@@ -3589,10 +3984,12 @@ namespace PEAPI {
                internal sealed override void TypeSig(MemoryStream sig) 
                {
                        sig.WriteByte((byte)callConv);
+                       if ((callConv & CallConv.Generic) == CallConv.Generic)
+                               MetaData.CompressNum ((uint) gen_param_count, sig);
                        MetaData.CompressNum((uint)numPars,sig);
-                       if (ret_param != null)
-                               ret_param.seqNo = 0;
-                       retType.TypeSig(sig);
+
+                       ret_param.seqNo = 0;
+                       ret_param.TypeSig (sig);
                        for (ushort i=0; i < numPars; i++) {
                                parList[i].seqNo = (ushort)(i+1);
                                parList[i].TypeSig(sig);
@@ -3621,7 +4018,7 @@ namespace PEAPI {
                        nameIx = md.AddToStringsHeap(name);
                        sigIx = GetSigIx(md);
                        parIx = md.TableIndex(MDTable.Param);
-                       if (ret_param != null) {
+                       if (ret_param.HasMarshalInfo || ret_param.HasCustomAttr) {
                                md.AddToTable(MDTable.Param, ret_param);
                                ret_param.BuildTables(md);
                        }
@@ -3688,23 +4085,42 @@ namespace PEAPI {
                Type[] parList, optParList;
                MetaDataElement parent;
                uint numPars = 0, numOptPars = 0;
+               CallConv callConv = CallConv.Default;
+               Type retType;
+               int gen_param_count;
 
                internal MethodRef(MetaDataElement paren, string name, Type retType,
-                               Type[] pars, bool varArgMeth, Type[] optPars) : base(name,retType) 
+                               Type[] pars, bool varArgMeth, Type[] optPars, int gen_param_count) : base(name)
                {
                        parent = paren;
                        parList = pars;
+                       this.retType = retType;
                        if (parList != null) numPars = (uint)parList.Length;
                        if (varArgMeth) {
                                optParList = optPars;
                                if (optParList != null) numOptPars = (uint)optParList.Length;
                                callConv = CallConv.Vararg;
                        }
+                       this.gen_param_count = gen_param_count;
                }
 
+               internal override uint GetSigIx(MetaData md)
+               {
+                       MemoryStream sig = new MemoryStream();
+                       TypeSig(sig);
+                       return md.AddToBlobHeap(sig.ToArray());
+               }
+
+               public override void AddCallConv(CallConv cconv)
+               {
+                       callConv |= cconv;
+               }
+               
                internal sealed override void TypeSig(MemoryStream sig) 
                {
                        sig.WriteByte((byte)callConv);
+                       if ((callConv & CallConv.Generic) == CallConv.Generic)
+                               MetaData.CompressNum ((uint) gen_param_count, sig);
                        MetaData.CompressNum(numPars+numOptPars,sig);
                        retType.TypeSig(sig);
                        for (int i=0; i < numPars; i++) {
@@ -3786,6 +4202,8 @@ namespace PEAPI {
                public static readonly NativeType VariantBool = new NativeType(0x25);
                public static readonly NativeType FuncPtr = new NativeType(0x26);
                public static readonly NativeType AsAny = new NativeType(0x28);
+               public static readonly NativeType LPStruct = new NativeType(0x2b);
+               public static readonly NativeType Error = new NativeType(0x2d);
 
                protected byte typeIndex;
 
@@ -4012,12 +4430,15 @@ namespace PEAPI {
                public static readonly PrimitiveType Float64 = new PrimitiveType(0x0D,"Double",12);
                public static readonly PrimitiveType String = new PrimitiveType(0x0E,"String",13);
                internal static readonly PrimitiveType Class = new PrimitiveType(0x12);
+               internal static readonly PrimitiveType Var = new PrimitiveType(0x13);
+               internal static readonly PrimitiveType GenericInst = new PrimitiveType(0x15);
                public static readonly PrimitiveType TypedRef = new PrimitiveType(0x16,"TypedReference",14);
                public static readonly PrimitiveType IntPtr = new PrimitiveType(0x18,"IntPtr",15);
                public static readonly PrimitiveType UIntPtr = new PrimitiveType(0x19,"UIntPtr",16);
                public static readonly PrimitiveType Object = new PrimitiveType(0x1C,"Object",17);
                internal static readonly PrimitiveType ClassType = new PrimitiveType(0x50);
                internal static readonly PrimitiveType SZArray = new PrimitiveType(0x1D);
+               internal static readonly PrimitiveType MVar = new PrimitiveType(0x1E);
                internal static readonly PrimitiveType ValueType = new PrimitiveType(0x11, "ValueType", 18);
                public static readonly PrimitiveType NativeInt = IntPtr;
                public static readonly PrimitiveType NativeUInt = UIntPtr;
@@ -4124,6 +4545,11 @@ namespace PEAPI {
                        tabIx = MDTable.AssemblyRef;
                }
 
+               public void AddAssemblyAttr (AssemAttr aa)
+               {
+                       flags |= (uint)aa;
+               }
+
                /// <summary>
                /// Add version information about this external assembly
                /// </summary>
@@ -4508,7 +4934,13 @@ namespace PEAPI {
                private static readonly uint max3BitSmlIx = 0x1FFF;
                private static readonly uint max5BitSmlIx = 0x7FF;
                // NOTE: version and stream name strings MUST always be quad padded
+#if NET_4_0 || BOOTSTRAP_NET_4_0
+               private static readonly string version = "v4.0.30319\0\0";
+#elif NET_2_0 || BOOTSTRAP_NET_2_0
+               private static readonly string version = "v2.0.50727\0\0";
+#else
                private static readonly string version = "v1.1.4322\0\0\0";
+#endif
                private static readonly char[] tildeName = {'#','~','\0','\0'};
                private static readonly char[] stringsName = {'#','S','t','r','i','n','g','s','\0','\0','\0','\0'};
                private static readonly char[] usName = {'#','U','S','\0'};
@@ -4694,7 +5126,7 @@ namespace PEAPI {
                        cattr_list.Add (cattr);
                }
 
-               internal void AddDeclSecurity (DeclSecurity decl_sec)
+               internal void AddDeclSecurity (BaseDeclSecurity decl_sec)
                {
                        if (declsec_list == null)
                                declsec_list = new ArrayList ();
@@ -4761,9 +5193,9 @@ namespace PEAPI {
 
                internal static void CompressNum(uint val, MemoryStream sig) 
                {
-                       if (val < 0x7F) {
+                       if (val <= 0x7F) {
                                sig.WriteByte((byte)val);
-                       } else if (val < 0x3FFF) {
+                       } else if (val <= 0x3FFF) {
                                byte b1 = (byte)((val >> 8) | 0x80);
                                byte b2 = (byte)(val & FileImage.iByteMask[0]);
                                sig.WriteByte(b1);
@@ -4913,8 +5345,13 @@ namespace PEAPI {
                {
                        long startTilde = output.Seek(0,SeekOrigin.Current);
                        output.Write((uint)0); // Reserved
+#if NET_2_0 || BOOTSTRAP_NET_2_0
+                       output.Write((byte)2); // MajorVersion
+                       output.Write((byte)0); // MinorVersion
+#else
                        output.Write((byte)1); // MajorVersion
                        output.Write((byte)0); // MinorVersion
+#endif
                        output.Write(heapSizes);
                        output.Write((byte)1); // Reserved
                        output.Write(valid);
@@ -4961,10 +5398,13 @@ namespace PEAPI {
                {
                        codeStart = codeStartOffset;
                        BuildTable(metaDataTables[(int)MDTable.TypeDef]);
+                       BuildTable(metaDataTables[(int)MDTable.TypeSpec]);
                        BuildTable(metaDataTables[(int)MDTable.MemberRef]);
+#if NET_2_0 || BOOTSTRAP_NET_2_0
                        BuildTable(metaDataTables[(int)MDTable.GenericParam]);
                        BuildTable(metaDataTables[(int)MDTable.MethodSpec]);
                        BuildTable(metaDataTables[(int)MDTable.GenericParamConstraint]);
+#endif
                        BuildTable(metaDataTables[(int)MDTable.ManifestResource]);
 
                        if (cattr_list != null) {
@@ -4973,7 +5413,7 @@ namespace PEAPI {
                        }
 
                        if (declsec_list != null) {
-                               foreach (DeclSecurity decl_sec in declsec_list)
+                               foreach (BaseDeclSecurity decl_sec in declsec_list)
                                        decl_sec.BuildTables (this);
                        }
 
@@ -5005,11 +5445,11 @@ namespace PEAPI {
                        // will _ALWAYS_ be in the correct order as embedded in BuildMDTables
 
                        SortTable(metaDataTables[(int)MDTable.Constant]);
-                       SortTable(metaDataTables[(int)MDTable.CustomAttribute]);
                        SortTable(metaDataTables[(int)MDTable.FieldMarshal]);
                        SortTable(metaDataTables[(int)MDTable.DeclSecurity]);
                        SortTable(metaDataTables[(int)MDTable.MethodSemantics]);
                        SortTable(metaDataTables[(int)MDTable.ImplMap]);
+#if NET_2_0 || BOOTSTRAP_NET_2_0
                        if (metaDataTables[(int)MDTable.GenericParam] != null) {
                                SortTable(metaDataTables[(int)MDTable.GenericParam]);
                                // Now add GenericParamConstraints
@@ -5018,7 +5458,9 @@ namespace PEAPI {
                                  }*/
                        }
                        SortTable(metaDataTables[(int)MDTable.GenericParamConstraint]);
+#endif 
                        SortTable(metaDataTables[(int)MDTable.InterfaceImpl]);
+                       SortTable(metaDataTables[(int)MDTable.CustomAttribute]);
 
                }
 
@@ -5088,11 +5530,11 @@ namespace PEAPI {
                                // Console.WriteLine("coded index = " + ix + " row = " + elem.Row);
                                //} else {
                                // Console.WriteLine("elem for coded index is null");
-               }
-               if (lgeCIx[(uint)code]) 
-                       output.Write(ix);
-               else
-                       output.Write((ushort)ix);
+                       }
+                       if (lgeCIx[(uint)code]) 
+                               output.Write(ix);
+                       else
+                               output.Write((ushort)ix);
                }
 
        }