using System.IO;
using System.Collections;
using System.Text;
+using System.Reflection;
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 }
/// <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
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}
/// 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
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
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
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,
protected bool done = false;
protected MDTable tabIx;
protected bool sortTable = false;
+ //Temporary hack..
+ private bool has_custom_attrs = false;
internal MetaDataElement() { }
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>
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());
}
/// 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()
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);
}
+ 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
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()
| owner.GetCodedIx(CIx.TypeOrMethodDef);
}
+ internal override uint SortKey2 ()
+ {
+ return (uint) index;
+ }
+
public void AddConstraint (Type constraint)
{
metadata.AddToTable (MDTable.GenericParamConstraint,
{
return (uint) (4 +
md.CodedIndexSize(CIx.TypeOrMethodDef) +
- 4 +
- md.TableIndexSize(MDTable.TypeDef));
+ md.StringsIndexSize ());
}
internal sealed override void BuildTables(MetaData md)
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;
+ }
}
tabIx = MDTable.GenericParamConstraint;
}
+ internal override uint SortKey()
+ {
+ return param.Row;
+ }
+
internal sealed override uint Size(MetaData md)
{
return (uint) (md.TableIndexSize(MDTable.GenericParam) +
}
- 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;
output.WriteCodedIndex (CIx.MethodDefOrRef, meth);
output.BlobIndex (sidx);
}
+
+ internal sealed override void TypeSig (MemoryStream sig)
+ {
+ throw new Exception ("Should not be used.");
+ }
}
/**************************************************************************/
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);
}
tabIx = MDTable.Param;
}
+ public bool HasMarshalInfo {
+ get { return marshalInfo != null; }
+ }
+
/// <summary>
/// Add a default value to this parameter
/// </summary>
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)
internal void SetSuper(Class sClass)
{
superType = sClass;
- if (sClass is ClassRef)
- typeIndex = superType.GetTypeIndex();
- else
+ if (! (sClass is GenericTypeInst))
typeIndexChecked = false;
}
/// </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;
}
/// <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;
}
/// <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;
}
internal void CheckTypeIndex()
{
if (typeIndexChecked) return;
- if (!(superType is ClassRef))
+ if (superType is ClassDef)
((ClassDef)superType).CheckTypeIndex();
typeIndex = superType.GetTypeIndex();
typeIndexChecked = true;
/// <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;
}
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;
}
}
- 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);
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);
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;
}
}
/// <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>
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
/// <summary>
/// Descriptor for THIS module
/// </summary>
- public class Module : ResolutionScope {
+ public class Module : ResolutionScope, IExternRef {
Guid mvid;
uint mvidIx = 0;
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();
/// <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;
}
/// <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;
}
}
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;
{
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;
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;
}
}
public class Property : Feature {
private static readonly byte PropertyTag = 0x8;
+ private bool instance;
MethodDef getterMeth;
ConstantElem constVal;
uint typeBlobIx = 0;
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++) {
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);
}
/**************************************************************************/
//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;
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;
}
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>
/// </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;
}
/* Add Marshal info for return type */
public void AddRetTypeMarshallInfo (NativeType marshallType)
{
- ret_param = new Param (ParamAttr.HasFieldMarshal, "", retType);
ret_param.AddMarshallInfo (marshallType);
}
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 ();
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);
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);
}
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++) {
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;
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;
tabIx = MDTable.AssemblyRef;
}
+ public void AddAssemblyAttr (AssemAttr aa)
+ {
+ flags |= (uint)aa;
+ }
+
/// <summary>
/// Add version information about this external assembly
/// </summary>
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'};
cattr_list.Add (cattr);
}
- internal void AddDeclSecurity (DeclSecurity decl_sec)
+ internal void AddDeclSecurity (BaseDeclSecurity decl_sec)
{
if (declsec_list == null)
declsec_list = new ArrayList ();
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);
{
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);
{
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) {
}
if (declsec_list != null) {
- foreach (DeclSecurity decl_sec in declsec_list)
+ foreach (BaseDeclSecurity decl_sec in declsec_list)
decl_sec.BuildTables (this);
}
// 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
}*/
}
SortTable(metaDataTables[(int)MDTable.GenericParamConstraint]);
+#endif
SortTable(metaDataTables[(int)MDTable.InterfaceImpl]);
+ SortTable(metaDataTables[(int)MDTable.CustomAttribute]);
}
// 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);
}
}