Bladeren bron

Fixes for issues id#5466, id#5467, id#5468.
Instructions.cs: some adding of missing instruction prefix names, minor refactoring.

MDMethodElems.cs: method signature generated on demand to avoid read-order issues; In MethodSpec the signature of the MethParent must be hoisted up to this; ClassSpec objects are added to the TypeSpec table conditionally, to avoid duplicate entries.

MDTypeElems.cs: typeSpecAdded field is moved from TypeSpec to Type, so as to apply to ClassSpec objects. Otherwise a TypeSpec wrapper class for ClassSpec would have been needed; In the same vein, the GenericParTypeSpec class that wraps a GenericParam for the TypeSpec list has to be referenced by the owning GenericParam so as no avoid duplicates losing object identity.

MetaDataOut.cs: conditional version of AddToTable for TypeSpec.

PEReader.cs: Extra clause in GetDataConstant to persist array initialization in .data

k_john_gough_cp 15 jaren geleden
bovenliggende
commit
742430a288
8 gewijzigde bestanden met toevoegingen van 200 en 133 verwijderingen
  1. 21 19
      PERWAPI/Instructions.cs
  2. 4 8
      PERWAPI/MDClassElems.cs
  3. 18 17
      PERWAPI/MDFieldElems.cs
  4. 22 10
      PERWAPI/MDMethodElems.cs
  5. 24 9
      PERWAPI/MDTypeElems.cs
  6. 19 11
      PERWAPI/MetaDataOut.cs
  7. 29 33
      PERWAPI/PEReader.cs
  8. 63 26
      PERWAPI/SectionClass.cs

+ 21 - 19
PERWAPI/Instructions.cs

@@ -1541,8 +1541,8 @@ namespace QUT.PERWAPI {
     protected static readonly string[] FEopcode = {
             "arglist", "ceq", "cgt", "cgt.un", "clt", "clt.un", "ldftn", "ldvirtftn",
             "ERROR", "ldarg", "ldarga", "starg", "ldloc", "ldloca", "stloc", "localloc",
-            "ERROR", "endfilter", "unaligned", "volatile", "tail", "initobj", "ERROR", "cpblk",
-            "initblk", "ERROR", "rethrow", "ERROR", "sizeof", "refanytype", "readonly"};
+            "ERROR", "endfilter", "unaligned", "volatile", "tail", "initobj", "constrained", "cpblk",
+            "initblk", "no.", "rethrow", "ERROR", "sizeof", "refanytype", "readonly"};
 
     /// <summary>
     /// A list of the delta distances for the given FE CIL instructions.
@@ -1550,8 +1550,8 @@ namespace QUT.PERWAPI {
     protected static readonly int[] FEopDeltaDistance = {
             1 /* arglist */, -1 /* ceq */, -1 /* cgt */, -1 /* cgt.un */, -1 /* clt */, -1 /* clt.un */, 1 /* ldftn */, 0 /* ldvirtftn */,
             -99 /* ERROR */, 1 /* ldarg */, 1 /* ldarga */, -1 /* starg */, 1 /* ldloc */, 1 /* ldloca */, -1 /* stloc */, 0 /* localloc */,
-            -99 /* ERROR */, -1 /* endfilter */, 0 /* unaligned */, 0 /* volatile */, 0 /* tail */, -1 /* initobj */, -99 /* ERROR */, -3 /* cpblk */,
-            -3 /* initblk */, -99 /* ERROR */, 0 /* rethrow */, -99 /* ERROR */, 1 /* sizeof */, 0 /* refanytype */, 0 /* readonly */};
+            -99 /* ERROR */, -1 /* endfilter */, 0 /* unaligned */, 0 /* volatile */, 0 /* tail */, -1 /* initobj */, 0 /* constrained */, -3 /* cpblk */,
+            -3 /* initblk */, 0 /* no. */, 0 /* rethrow */, -99 /* ERROR */, 1 /* sizeof */, 0 /* refanytype */, 0 /* readonly */};
 
     internal bool twoByteInstr = false;
     internal uint size = 1;
@@ -1675,7 +1675,7 @@ namespace QUT.PERWAPI {
       }
     }
 
-    public virtual string ToString() { return this.GetInstrString(); }
+    public override string ToString() { return this.GetInstrString(); }
 
     /// <summary>
     /// Get the delta distance for this instruction.
@@ -1966,7 +1966,7 @@ namespace QUT.PERWAPI {
       output.WriteLine("Label" + num + ":");
     }
 
-    public virtual string ToString() { return "label"; }
+    public override string ToString() { return "label"; }
   }
 
   /**************************************************************************/
@@ -2104,7 +2104,7 @@ namespace QUT.PERWAPI {
       }
     }
 
-    public virtual string ToString() { 
+    public override string ToString() { 
       return String.Format("line {0}:{1}-{2}:{3}", this.startLine, this.startCol, this.endLine, this.endCol); 
     }
   }
@@ -2501,7 +2501,7 @@ namespace QUT.PERWAPI {
       }
     }
 
-    public virtual string ToString() { return "Open scope"; }
+    public override string ToString() { return "Open scope"; }
   }
   /************************************************************************/
 
@@ -2550,8 +2550,9 @@ namespace QUT.PERWAPI {
         output.pdbWriter.CloseScope((int)offset);
     }
 
-    public virtual string ToString() { return "Close scope"; }
+    public override string ToString() { return "Close scope"; }
   }
+
   /**************************************************************************/
 
   public class FieldInstr : Instr {
@@ -2645,21 +2646,22 @@ namespace QUT.PERWAPI {
     /// </remarks>
     /// <returns>An integer value representing the delta distance.</returns>
     internal override int GetDeltaDistance() {
+      MethSig mSig = null;
       switch ((MethodOp)instr) {
         case MethodOp.callvirt:
         case MethodOp.call: {
-
+            mSig = meth.GetSig();
             // Add the parameter count to the depth
-            int depth = (int)meth.GetSig().numPars * -1;
+            int depth = (int)mSig.numPars * -1;
 
             // Check to see if this is an instance method
-            if (meth.GetSig().HasCallConv(CallConv.Instance)) depth--;
+            if (mSig.HasCallConv(CallConv.Instance)) depth--;
 
             // Check to see if this method uses the optional parameters
-            if (meth.GetSig().HasCallConv(CallConv.Vararg)) depth += (int)meth.GetSig().numOptPars * -1;
+            if (mSig.HasCallConv(CallConv.Vararg)) depth += (int)mSig.numOptPars * -1;
 
             // Check to see if this method uses the generic parameters
-            if (meth.GetSig().HasCallConv(CallConv.Generic)) depth += (int)meth.GetSig().numGenPars * -1;
+            if (mSig.HasCallConv(CallConv.Generic)) depth += (int)mSig.numGenPars * -1;
 
             // Check if a return value will be placed on the stack.
             if (!meth.GetRetType().SameType(PrimitiveType.Void)) depth++;
@@ -2667,15 +2669,15 @@ namespace QUT.PERWAPI {
             return depth;
           }
         case MethodOp.newobj: {
-
+            mSig = meth.GetSig();
             // Add the parameter count to the depth
-            int depth = (int)meth.GetSig().numPars * -1;
+            int depth = (int)mSig.numPars * -1;
 
             // Check to see if this method uses the optional parameters
-            if (meth.GetSig().HasCallConv(CallConv.Vararg)) depth += (int)meth.GetSig().numOptPars * -1;
+            if (mSig.HasCallConv(CallConv.Vararg)) depth += (int)mSig.numOptPars * -1;
 
             // Check to see if this method uses the generic parameters
-            if (meth.GetSig().HasCallConv(CallConv.Generic)) depth += (int)meth.GetSig().numGenPars * -1;
+            if (mSig.HasCallConv(CallConv.Generic)) depth += (int)mSig.numGenPars * -1;
 
             // Add the object reference that is loaded onto the stack
             depth++;
@@ -2690,7 +2692,7 @@ namespace QUT.PERWAPI {
           return 0;
         default:
           // Someone has added a new MethodOp and not added a case for it here.
-          throw new Exception("The MethodOp for this MethoInstr is not supported.");
+          throw new Exception("The MethodOp for this MethInstr is not supported.");
       }
     }
 

+ 4 - 8
PERWAPI/MDClassElems.cs

@@ -392,9 +392,6 @@ namespace QUT.PERWAPI
             for (int i = 0; i < classFields.Count; i++)
             {
                 Type fType = ((Field)classFields[i]).GetFieldType();
-                //if ((fType is GenericParam) && (((GenericParam)fType).GetParent() == genClass)) {
-                //  fType = gPars[((GenericParam)fType).Index];
-                //}
                 fields.Add(new FieldRef(this, ((Field)classFields[i]).Name(), fType));
             }
         }
@@ -477,11 +474,10 @@ namespace QUT.PERWAPI
             //return (Type)genericParams[(int)ix];
         }
 
-        internal override sealed Type AddTypeSpec(MetaDataOut md)
-        {
-            md.AddToTable(MDTable.TypeSpec, this);
-            BuildMDTables(md);
-            return this;
+        internal override sealed Type AddTypeSpec(MetaDataOut md) {
+          md.AddToTable(MDTable.TypeSpec, this);
+          BuildMDTables(md);
+          return this;
         }
 
         internal override void BuildTables(MetaDataOut md)

+ 18 - 17
PERWAPI/MDFieldElems.cs

@@ -173,21 +173,22 @@ namespace QUT.PERWAPI
 
         internal void Resolve(PEReader buff, uint fIx)
         {
-            /*
-            if ((flags & HasFieldMarshal) != 0) 
-              marshalType = FieldMarshal.FindMarshalType(buff,this,
-                buff.MakeCodedIndex(CIx.HasFieldMarshal,MDTable.Field,fIx));
-            if ((flags & HasFieldRVA) != 0)
-              initVal = FieldRVA.FindValue(buff,this,fIx);
-            if ((flags & HasDefault) != 0)
-              constVal = ConstantElem.FindConst(buff,this,
-                buff.MakeCodedIndex(CIx.HasConstant,MDTable.Field,fIx));
-            long offs = FieldLayout.FindLayout(buff,this,fIx);
-            if (offs > -1){
-              hasOffset = true;
-              offset = (uint)offs;
-            }
-            */
+ 
+            //if ((flags & HasFieldMarshal) != 0) 
+            //  marshalType = FieldMarshal.FindMarshalType(buff,this,
+            //    buff.MakeCodedIndex(CIx.HasFieldMarshal,MDTable.Field,fIx));
+            //if ((flags & HasFieldRVA) != 0) {
+            //initVal = FieldRVA.FindValue(buff, this, fIx);
+            //}
+            //if ((flags & HasDefault) != 0)
+            //  constVal = ConstantElem.FindConst(buff,this,
+            //    buff.MakeCodedIndex(CIx.HasConstant,MDTable.Field,fIx));
+            //long offs = FieldLayout.FindLayout(buff,this,fIx);
+            //if (offs > -1){
+            //  hasOffset = true;
+            //  offset = (uint)offs;
+            //}
+
             buff.currentClassScope = parent;
             type = buff.GetFieldType(sigIx);
             buff.currentClassScope = null;
@@ -508,8 +509,8 @@ namespace QUT.PERWAPI
                 type.BuildMDTables(md);
             if (parent != null)
             {
-                if (parent is ClassSpec) md.AddToTable(MDTable.TypeSpec, parent);
-                parent.BuildMDTables(md);
+              if (parent is ClassSpec) md.AddToTable(MDTable.TypeSpec, parent);
+              parent.BuildMDTables(md);
             }
         }
 

+ 22 - 10
PERWAPI/MDMethodElems.cs

@@ -185,6 +185,13 @@ namespace QUT.PERWAPI
 
         internal MethSig GetSig() { return sig; }
 
+        internal MethSig GetSig(PEReader buff) {
+          if (sig == null)
+            sig = buff.ReadMethSig(this, this.sigIx);
+          return sig;
+        }
+
+
         internal void SetSig(MethSig sig)
         {
             this.sig = sig;
@@ -287,15 +294,20 @@ namespace QUT.PERWAPI
                 specs[i] = new MethodSpec(buff);
         }
 
-        internal override void Resolve(PEReader buff)
-        {
-            methParent = (Method)buff.GetCodedElement(CIx.MethodDefOrRef, parentIx);
-            buff.currentMethodScope = methParent;  // set scopes - Fix by CK
-            buff.currentClassScope = (Class)methParent.GetParent();
-            instTypes = buff.ReadMethSpecSig(instIx);
-            this.unresolved = false;
-            buff.currentMethodScope = null;
-            buff.currentClassScope = null;
+        internal override void Resolve(PEReader buff) {
+          methParent = (Method)buff.GetCodedElement(CIx.MethodDefOrRef, parentIx);
+          buff.currentMethodScope = methParent;  // set scopes - Fix by CK
+          buff.currentClassScope = (Class)methParent.GetParent();
+          //
+          // EXPERIMENTAL: The signature of the methParent must be
+          // visible as the signature of this MethodSpec.  The type-actuals
+          // are held in the instTypes array.
+          this.sig = this.methParent.GetSig(buff);
+          instTypes = buff.ReadMethSpecSig(instIx);
+          this.unresolved = false;
+          //
+          buff.currentMethodScope = null;
+          buff.currentClassScope = null;
         }
 
         internal override void TypeSig(MemoryStream str)
@@ -520,7 +532,7 @@ namespace QUT.PERWAPI
             nameIx = md.AddToStringsHeap(name);
             if (parent != null)
             {
-                if (parent is ClassSpec) md.AddToTable(MDTable.TypeSpec, parent);
+                if (parent is ClassSpec) md.ConditionalAddToTable(MDTable.TypeSpec, parent);
                 if (parent is ConstructedTypeSpec) 
                     md.AddToTable(MDTable.TypeSpec, ((ConstructedTypeSpec)parent).Spec);
                 parent.BuildMDTables(md);

+ 24 - 9
PERWAPI/MDTypeElems.cs

@@ -31,6 +31,12 @@ namespace QUT.PERWAPI
     {
         protected byte typeIndex;
 
+      /// <summary>
+      /// The following is only used for TypeSpecs and ClassSpecs. kjg
+      /// </summary>
+        internal bool typeSpecAdded = false; // so that MetaDataOut can reset it
+
+
         /*-------------------- Constructors ---------------------------------*/
 
         internal Type(byte tyIx) { typeIndex = tyIx; }
@@ -153,7 +159,7 @@ namespace QUT.PERWAPI
     {
 
         uint sigIx = 0;
-        internal bool typeSpecAdded = false; // so that MetaDataOut can reset it
+        //internal bool typeSpecAdded = false; // so that MetaDataOut can reset it
 
         /*-------------------- Constructors ---------------------------------*/
 
@@ -311,7 +317,7 @@ namespace QUT.PERWAPI
 
     /**************************************************************************/
     /// <summary>
-    /// Descriptor for  
+    /// Descriptor for a generic parameter for either a class or method. 
     /// </summary>
     public class GenericParam : Type
     {
@@ -324,6 +330,10 @@ namespace QUT.PERWAPI
         private ArrayList constraints = new ArrayList();
         internal static bool extraField = true;
 
+        // There should only be one GenericParTypeSpec entry 
+        // int the metadata for each GenericParam.
+        GenericParTypeSpec myTypeSpec;
+
         /*-------------------- Constructors ---------------------------------*/
 
         private GenericParam(uint index, byte elemIx)
@@ -517,12 +527,15 @@ namespace QUT.PERWAPI
 
         internal override Type AddTypeSpec(MetaDataOut md)
         {
-            // check that this generic parameter belongs to the "current" method ??
-            GenericParTypeSpec tSpec = new GenericParTypeSpec(this);
-            md.AddToTable(MDTable.TypeSpec, tSpec);
-            return tSpec;
+          if (this.myTypeSpec == null) {
+            this.myTypeSpec = new GenericParTypeSpec(this);
+            md.AddToTable(MDTable.TypeSpec, this.myTypeSpec);
+          }
+          return this.myTypeSpec;
         }
 
+        
+
         internal override uint SortKey()
         {
             return (parent.Row << MetaData.CIxShiftMap[(uint)CIx.TypeOrMethodDef])
@@ -599,7 +612,7 @@ namespace QUT.PERWAPI
 
     /**************************************************************************/
     /// <summary>
-    /// 
+    /// Wrapper for Generic Parameter of TypeSpec type.
     /// </summary> 
     public class GenericParTypeSpec : TypeSpec
     {
@@ -646,7 +659,9 @@ namespace QUT.PERWAPI
 
     /**************************************************************************/
     /// <summary>
-    /// The IL Array type
+    /// The IL Array type: there are two sub-classes --
+    /// BoundArrays, possibly multi dimensional arrays with bounds.
+    /// ZeroBasedArrays, built-in 1-D arrays of the CLR
     /// </summary>
     public abstract class Array : TypeSpec
     {
@@ -682,7 +697,7 @@ namespace QUT.PERWAPI
 
     /**************************************************************************/
     /// <summary>
-    /// Multi dimensional array with explicit bounds
+    /// Arrays with one or more dimensions, with explicit bounds
     /// </summary>
     public class BoundArray : Array
     {

+ 19 - 11
PERWAPI/MetaDataOut.cs

@@ -189,18 +189,26 @@ namespace QUT.PERWAPI
             return tables[tabIx];
         }
 
-        internal void AddToTable(MDTable tableIx, MetaDataElement elem)
-        {
-            // updates Row field of the element
-            // Console.WriteLine("Adding element to table " + (uint)tableIx);
-            ArrayList table = GetTable(tableIx);
-            if (table.Contains(elem))
-            {
-                Console.Out.WriteLine("ERROR - element already in table " + tableIx);
-                return;
-            }
+        internal void AddToTable(MDTable tableIx, MetaDataElement elem) {
+          // updates Row field of the element
+          // Console.WriteLine("Adding element to table " + (uint)tableIx);
+          ArrayList table = GetTable(tableIx);
+          if (table.Contains(elem)) {
+            Console.Out.WriteLine("ERROR - element already in table " + tableIx);
+            return;
+          }
+          elem.Row = (uint)table.Count + 1;
+          table.Add(elem);
+        }
+
+        internal void ConditionalAddToTable(MDTable tableIx, MetaDataElement elem) {
+          // updates Row field of the element
+          // Console.WriteLine("Adding element to table " + (uint)tableIx);
+          ArrayList table = GetTable(tableIx);
+          if (!table.Contains(elem)) {
             elem.Row = (uint)table.Count + 1;
             table.Add(elem);
+          }
         }
 
         internal uint TableIndex(MDTable tableIx)
@@ -337,7 +345,7 @@ namespace QUT.PERWAPI
                 ArrayList typeSpecTable = tables[(int)MDTable.TypeSpec];
                 for (int i = 0; i < typeSpecTable.Count; i++)
                 {
-                    ((TypeSpec)typeSpecTable[i]).typeSpecAdded = false;
+                  ((Type)typeSpecTable[i]).typeSpecAdded = false;
                 }
             }
             //Console.WriteLine("Writing padding at " + output.Seek(0,SeekOrigin.Current));

+ 29 - 33
PERWAPI/PEReader.cs

@@ -805,10 +805,6 @@ namespace QUT.PERWAPI
                         {
                             ((MetaDataElement)tables[ix][j]).Resolve(this);
                         }
-                        else
-                        {
-                            Console.WriteLine();
-                        }
                     }
                 }
             }
@@ -1092,8 +1088,6 @@ namespace QUT.PERWAPI
 
         private MethSig ReadMethSig(Method currMeth, bool firstByteRead)
         {
-            //Class currClass = null;
-            //if (currMeth != null) currClass = (Class)currMeth.GetParent();
             MethSig meth = new MethSig(null);
             if (!firstByteRead)
             {
@@ -1108,9 +1102,7 @@ namespace QUT.PERWAPI
                 if (currMeth is MethodRef)
                 {
                     ((MethodRef)currMeth).MakeGenericPars(meth.numGenPars);
-                } //else if (currMeth is MethodDef) {
-                //GetGenericParams((MethodDef)currMeth);
-                //}
+                }
             }
             uint parCount = blob.ReadCompressedNum();
             if (Diag.DiagOn) Console.WriteLine("Method sig has " + parCount + " parameters");
@@ -1180,12 +1172,12 @@ namespace QUT.PERWAPI
         }
 
         private Type[] GetListOfType()
-        { //Class currClass, Method currMeth) {
+        { //Class currClass | Method currMeth) {
             uint numPars = blob.ReadCompressedNum();
             Type[] gPars = new Type[numPars];
             for (int i = 0; i < numPars; i++)
             {
-                gPars[i] = GetBlobType(); //currClass,currMeth);
+                gPars[i] = GetBlobType(); //currClass|currMeth);
             }
             return gPars;
         }
@@ -1351,29 +1343,33 @@ namespace QUT.PERWAPI
             prop.SetPropertyParams(pars);
         }
 
-        internal DataConstant GetDataConstant(uint rva, Type constType)
-        {
-            BaseStream.Seek(GetOffset(rva), SeekOrigin.Begin);
-            if (constType is PrimitiveType)
-            {
-                switch (constType.GetTypeIndex())
-                {
-                    case ((int)ElementType.I1): return new IntConst(ReadByte());
-                    case ((int)ElementType.I2): return new IntConst(ReadInt16());
-                    case ((int)ElementType.I4): return new IntConst(ReadInt32());
-                    case ((int)ElementType.I8): return new IntConst(ReadInt64());
-                    case ((int)ElementType.R4): return new FloatConst(ReadSingle());
-                    case ((int)ElementType.R8): return new DoubleConst(ReadDouble());
-                    case ((int)ElementType.String): return new StringConst(ReadString());
-                }
+        internal DataConstant GetDataConstant(uint rva, Type constType) {
+          ManagedPointer pointer = null;
+          ClassDef image = null;
+          BaseStream.Seek(GetOffset(rva), SeekOrigin.Begin);
+          if (constType is PrimitiveType) {
+            switch (constType.GetTypeIndex()) {
+              case ((int)ElementType.I1): return new IntConst(ReadByte());
+              case ((int)ElementType.I2): return new IntConst(ReadInt16());
+              case ((int)ElementType.I4): return new IntConst(ReadInt32());
+              case ((int)ElementType.I8): return new IntConst(ReadInt64());
+              case ((int)ElementType.R4): return new FloatConst(ReadSingle());
+              case ((int)ElementType.R8): return new DoubleConst(ReadDouble());
+              case ((int)ElementType.String): return new StringConst(ReadString());
             }
-            else if (constType is ManagedPointer)
-            {
-                uint dataRVA = ReadUInt32();
-                Type baseType = ((ManagedPointer)constType).GetBaseType();
-                return new AddressConstant(GetDataConstant(dataRVA, baseType));
-            } // need to do repeated constant??
-            return null;
+          }
+          else if ((pointer = constType as ManagedPointer) != null) {
+            uint dataRVA = ReadUInt32();
+            Type baseType = pointer.GetBaseType();
+            return new AddressConstant(GetDataConstant(dataRVA, baseType));
+          } // need to do repeated constant??
+          else if ((image = constType as ClassDef) != null && image.Layout != null) {
+            byte[] data = new byte[image.Layout.GetSize()];
+            for (int i = 0; i < data.Length; i++)
+              data[i] = ReadByte();
+            return new ByteArrConst(data);
+          }
+          return null;
         }
 
         internal ModuleFile GetFileDesc(string name)

+ 63 - 26
PERWAPI/SectionClass.cs

@@ -33,13 +33,48 @@ namespace QUT.PERWAPI
     {
         internal static readonly uint relocPageSize = 4096;  // 4K pages for fixups
 
+      /// <summary>
+      /// Eight characters exactly, null padded if necessary.
+      /// </summary>
         char[] name;
         string nameString;
-        uint offset = 0, tide = 0, size = 0, rva = 0, relocTide = 0, numRelocs = 0;
-        uint relocOff = 0, relocRVA = 0, lineRVA = 0, numLineNums = 0;
-        uint flags = 0, padding = 0;
+
+      /// <summary>
+      /// Total size of the section in bytes. If this value is 
+      /// greater than SizeOFRawData the section is zero-padded.
+      /// </summary>
+        uint loadedSize = 0;
+
+      /// <summary>
+      /// Position in memory when loaded, relative to image base.
+      /// </summary>
+        uint loadedRVA = 0;
+
+      /// <summary>
+      /// Size of raw data in the section. Must be multiple of file alignment size.
+      /// Can be smaller than loadedSize, or larger (as a result of alignment).
+      /// </summary>
+        uint sizeOnDisk = 0;
+
+      /// <summary>
+      /// Offset to section's page within the PE file.  Must be multiple
+      /// of file alignment constant.
+      /// </summary>
+        uint fileOffset = 0;
+
+      // These are all zero mostly.
+        uint relocRVA, lineRVA, relocOff, numRelocs, numLineNums = 0;
+
+      /// <summary>
+      /// Flags of section: code = 0x20, init-data = 0x40, un-init-data = 0x80, 
+      /// execute = 0x20000000, read = 0x40000000, write = 0x80000000.
+      /// </summary>
+        uint flags;
+
+        uint relocTide = 0;
+        uint padding = 0;
         uint[] relocs;
-        //bool relocsDone = false;
+
 
         internal Section(string sName, uint sFlags)
         {
@@ -54,10 +89,10 @@ namespace QUT.PERWAPI
             for (int i = 0; i < name.Length; i++)
                 name[i] = (char)input.ReadByte();
             nameString = new String(name);
-            tide = input.ReadUInt32();
-            rva = input.ReadUInt32();
-            size = input.ReadUInt32();
-            offset = input.ReadUInt32();
+            loadedSize = input.ReadUInt32();
+            loadedRVA = input.ReadUInt32();
+            sizeOnDisk = input.ReadUInt32();
+            fileOffset = input.ReadUInt32();
             relocRVA = input.ReadUInt32();
             lineRVA = input.ReadUInt32();
             numRelocs = input.ReadUInt16();
@@ -65,49 +100,51 @@ namespace QUT.PERWAPI
             flags = input.ReadUInt32();
             if (Diag.DiagOn)
             {
-                Console.WriteLine("  " + nameString + " RVA = " + Hex.Int(rva) + "  vSize = " + Hex.Int(tide));
-                Console.WriteLine("        FileOffset = " + Hex.Int(offset) + "  aSize = " + Hex.Int(size));
+                Console.WriteLine("  " + nameString + " RVA = " + Hex.Int(loadedRVA) + "  vSize = " + Hex.Int(loadedSize));
+                Console.WriteLine("        FileOffset = " + Hex.Int(fileOffset) + "  aSize = " + Hex.Int(sizeOnDisk));
             }
         }
 
         internal bool ContainsRVA(uint rvaPos)
         {
-            return (rva <= rvaPos) && (rvaPos <= rva + tide);
+            return (loadedRVA <= rvaPos) && (rvaPos <= loadedRVA + loadedSize);
         }
+
         internal uint GetOffset(uint inRVA)
         {
             uint offs = 0;
-            if ((rva <= inRVA) && (inRVA <= rva + tide))
-                offs = offset + (inRVA - rva);
+            if ((loadedRVA <= inRVA) && (inRVA <= loadedRVA + loadedSize))
+                offs = fileOffset + (inRVA - loadedRVA);
             return offs;
         }
-        internal uint Tide() { return tide; }
 
-        internal void IncTide(uint incVal) { tide += incVal; }
+        internal uint Tide() { return loadedSize; }
+
+        internal void IncTide(uint incVal) { loadedSize += incVal; }
 
         internal uint Padding() { return padding; }
 
-        internal uint Size() { return size; }
+        internal uint Size() { return sizeOnDisk; }
 
         internal void SetSize(uint pad)
         {
             padding = pad;
-            size = tide + padding;
+            sizeOnDisk = loadedSize + padding;
         }
 
-        internal uint RVA() { return rva; }
+        internal uint RVA() { return loadedRVA; }
 
-        internal void SetRVA(uint rva) { this.rva = rva; }
+        internal void SetRVA(uint loadedRVA) { this.loadedRVA = loadedRVA; }
 
-        internal uint Offset() { return offset; }
+        internal uint Offset() { return fileOffset; }
 
-        internal void SetOffset(uint offs) { offset = offs; }
+        internal void SetOffset(uint offs) { fileOffset = offs; }
 
         internal void DoBlock(BinaryWriter reloc, uint page, int start, int end)
         {
             //Console.WriteLine("rva = " + rva + "  page = " + page);
             if (Diag.DiagOn) Console.WriteLine("writing reloc block at " + reloc.BaseStream.Position);
-            reloc.Write(rva + page);
+            reloc.Write(loadedRVA + page);
             uint blockSize = (uint)(((end - start + 1) * 2) + 8);
             reloc.Write(blockSize);
             if (Diag.DiagOn) Console.WriteLine("Block size = " + blockSize);
@@ -183,10 +220,10 @@ namespace QUT.PERWAPI
         {
             if (Diag.DiagOn) Console.WriteLine("relocTide = " + relocTide);
             output.Write(name);
-            output.Write(tide);                 // Virtual size
-            output.Write(rva);                  // Virtual address
-            output.Write(size);                 // SizeOfRawData
-            output.Write(offset);               // PointerToRawData
+            output.Write(loadedSize);                 // Virtual size
+            output.Write(loadedRVA);                  // Virtual address
+            output.Write(sizeOnDisk);                 // SizeOfRawData
+            output.Write(fileOffset);               // PointerToRawData
             if (relocTide > 0)
             {
                 output.Write(relocRVA + relocOff);