/// <summary>
        /// Initializes a new instance of the <see cref="MemberOperand"/> class.
        /// </summary>
        /// <param name="method">The method to reference.</param>
        /// <exception cref="System.ArgumentNullException"><paramref name="method"/> is null.</exception>
        public MemberOperand(RuntimeMethod method)
            : base(new SigType(CilElementType.I), null, IntPtr.Zero)
        {
            if (method == null)
                throw new ArgumentNullException(@"method");

            this.member = method;
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="MemberOperand"/> class.
        /// </summary>
        /// <param name="member">The member to reference.</param>
        /// <param name="type">The type of data held in the operand.</param>
        /// <param name="offset">The offset From the base register or absolute address to retrieve.</param>
        public MemberOperand(RuntimeMember member, SigType type, IntPtr offset)
            : base(type, null, offset)
        {
            if (member == null)
                throw new ArgumentNullException(@"member");

            this.member = member;
        }
        /// <summary>
        /// Initializes a new instance of <see cref="MemberOperand"/>.
        /// </summary>
        /// <param name="field">The runtime field to reference.</param>
        /// <exception cref="System.ArgumentNullException"><paramref name="field"/> is null.</exception>
        public MemberOperand(RuntimeField field)
            : base(field.Type, null, IntPtr.Zero)
        {
            if (field == null)
                throw new ArgumentNullException(@"field");

            this.member = field;
        }
Beispiel #4
0
 /// <summary>
 /// Issues a linker request for the given runtime method.
 /// </summary>
 /// <param name="linkType">The type of link required.</param>
 /// <param name="method">The method the patched code belongs to.</param>
 /// <param name="methodOffset">The offset inside the method where the patch is placed.</param>
 /// <param name="methodRelativeBase">The base virtualAddress, if a relative link is required.</param>
 /// <param name="target">The method or static field to link against.</param>
 /// <param name="offset">An offset to apply to the link target.</param>
 /// <returns></returns>
 public override long Link(LinkType linkType, RuntimeMethod method, int methodOffset, int methodRelativeBase, RuntimeMember target, IntPtr offset)
 {
     return base.Link(linkType, method, methodOffset, methodRelativeBase, target, offset);
 }
 /// <summary>
 /// Checks that <paramref name="member"/> is a member, which can be linked.
 /// </summary>
 /// <param name="member">The member to check.</param>
 /// <returns>
 /// True, if the member is valid for linking.
 /// </returns>
 protected bool IsValid(RuntimeMember member)
 {
     return (member is RuntimeMethod || (member is RuntimeField && FieldAttributes.Static == (FieldAttributes.Static & ((RuntimeField)member).Attributes)));
 }
 /// <summary>
 /// Issues a linker request for the given runtime method.
 /// </summary>
 /// <param name="linkType">The type of link required.</param>
 /// <param name="method">The method the patched code belongs to.</param>
 /// <param name="methodOffset">The offset inside the method where the patch is placed.</param>
 /// <param name="methodRelativeBase">The base virtualAddress, if a relative link is required.</param>
 /// <param name="target">The method or static field to link against.</param>
 /// <param name="offset">An offset to apply to the link target.</param>
 /// <returns>
 /// The return value is the preliminary virtualAddress to place in the generated machine
 /// code. On 32-bit systems, only the lower 32 bits are valid. The above are not used. An implementation of
 /// IAssemblyLinker may not rely on 64-bits being stored in the memory defined by position.
 /// </returns>
 public long Link(LinkType linkType, RuntimeMethod method, int methodOffset, int methodRelativeBase, RuntimeMember target, IntPtr offset)
 {
     CheckImplementation();
     return this.implementation.Link(linkType, method, methodOffset, methodRelativeBase, target, offset);
 }
 /// <summary>
 /// Retrieves a linker symbol.
 /// </summary>
 /// <param name="member">The runtime member to retrieve a symbol for.</param>
 /// <returns>
 /// A linker symbol, which represents the runtime member.
 /// </returns>
 public LinkerSymbol GetSymbol(RuntimeMember member)
 {
     CheckImplementation();
     return this.implementation.GetSymbol(member);
 }
 /// <summary>
 /// Creates a canonical symbol name for the given runtime member
 /// </summary>
 /// <param name="member">The runtime member to create a symbol name for</param>
 /// <returns>A string containing the canonical symbol name for the given runtime member</returns>
 public string CreateSymbolName(RuntimeMember member)
 {
     CheckImplementation();
     return this.implementation.CreateSymbolName(member);
 }
 /// <summary>
 /// Allocates memory in the specified section.
 /// </summary>
 /// <param name="symbol">The metadata member to allocate space for.</param>
 /// <param name="section">The executable section to allocate From.</param>
 /// <param name="size">The number of bytes to allocate. If zero, indicates an unknown amount of memory is required.</param>
 /// <param name="alignment">The alignment. A value of zero indicates the use of a default alignment for the section.</param>
 /// <returns>A stream, which can be used to populate the section.</returns>
 public Stream Allocate(RuntimeMember symbol, SectionKind section, int size, int alignment)
 {
     CheckImplementation();
     return this.implementation.Allocate(symbol, section, size, alignment);
 }
        /// <summary>
        /// Allocates memory in the specified section.
        /// </summary>
        /// <param name="member">The metadata member to allocate space for.</param>
        /// <param name="section">The executable section to allocate From.</param>
        /// <param name="size">The number of bytes to allocate. If zero, indicates an unknown amount of memory is required.</param>
        /// <param name="alignment">The alignment. A value of zero indicates the use of a default alignment for the section.</param>
        /// <returns>A stream, which can be used to populate the section.</returns>
        public virtual Stream Allocate(RuntimeMember member, SectionKind section, int size, int alignment)
        {
            // Create a canonical symbol name
            string name = CreateSymbolName(member);

            // Create a stream
            return Allocate(name, section, size, alignment);
        }
        /// <summary>
        /// Determines if the given runtime member can be resolved immediately.
        /// </summary>
        /// <param name="member">The runtime member to determine resolution of.</param>
        /// <param name="virtualAddress">Receives the determined virtualAddress of the runtime member.</param>
        /// <returns>
        /// The method returns true, when it was successfully resolved.
        /// </returns>
        protected bool IsResolved(RuntimeMember member, out long virtualAddress)
        {
            // Is this a method?
            RuntimeMethod method = member as RuntimeMethod;
            if (null != method && method.ImplAttributes == MethodImplAttributes.InternalCall) {
                virtualAddress = ResolveInternalCall(method);
                return (0 != virtualAddress);
            }

            return IsResolved(CreateSymbolName(member), out virtualAddress);
        }
        /// <summary>
        /// Issues a linker request for the given runtime method.
        /// </summary>
        /// <param name="linkType">The type of link required.</param>
        /// <param name="method">The method the patched code belongs to.</param>
        /// <param name="methodOffset">The offset inside the method where the patch is placed.</param>
        /// <param name="methodRelativeBase">The base virtualAddress, if a relative link is required.</param>
        /// <param name="target">The method or static field to link against.</param>
        /// <param name="offset">An offset to apply to the link target.</param>
        public virtual long Link(LinkType linkType, RuntimeMethod method, int methodOffset, int methodRelativeBase, RuntimeMember target, IntPtr offset)
        {
            Debug.Assert(IsValid(target), @"Invalid RuntimeMember passed to IAssemblyLinker.Link");
            if (!IsValid(target))
                throw new ArgumentException(@"RuntimeMember is not a static field or method.", @"member");

            long address;
            if (!IsResolved(target, out address)) {
                address = Link(linkType, method, methodOffset, methodRelativeBase, CreateSymbolName(target), offset);
            }
            else {
                address += offset.ToInt64();
            }

            return address;
        }
        /// <summary>
        /// Retrieves a linker symbol.
        /// </summary>
        /// <param name="member">The runtime member to retrieve a symbol for.</param>
        /// <returns>
        /// A linker symbol, which represents the runtime member.
        /// </returns>
        /// <exception cref="System.ArgumentNullException"><paramref name="member"/> is null.</exception>
        /// <exception cref="System.ArgumentException">There's no symbol of the given name.</exception>
        public LinkerSymbol GetSymbol(RuntimeMember member)
        {
            if (member == null)
                throw new ArgumentNullException(@"member");

            string symbolName = CreateSymbolName(member);
            return GetSymbol(symbolName);
        }
        /// <summary>
        /// Creates a symbol name.
        /// </summary>
        /// <param name="symbol">The symbol name.</param>
        /// <returns>A string, which represents the symbol name.</returns>
        public string CreateSymbolName(RuntimeMember symbol)
        {
            if (symbol == null)
                throw new ArgumentNullException(@"symbol");

            if (symbol is RuntimeMethod)
                return CreateSymbolName(symbol as RuntimeMethod);
            else if (symbol is RuntimeType)
                return CreateSymbolName(symbol as RuntimeType);
            else {
                string name;
                RuntimeType declaringType = symbol.DeclaringType;
                if (declaringType != null) {
                    string declaringTypeSymbolName = CreateSymbolName(declaringType);
                    name = String.Format("{0}.{1}", declaringTypeSymbolName, symbol.Name);
                }
                else {
                    name = symbol.Name;
                }

                return name;
            }
        }
Beispiel #15
0
 /// <summary>
 /// Issues a linker request for the given runtime method.
 /// </summary>
 /// <param name="method">The method the patched code belongs to.</param>
 /// <param name="methodOffset">The offset inside the method where the patch is placed.</param>
 /// <param name="linkType">The type of link required.</param>
 /// <param name="methodRelativeBase">The base address, if a relative link is required.</param>
 /// <param name="target">The method or static field to link against.</param>
 /// <returns>
 /// The return value is the preliminary address to place in the generated machine 
 /// code. On 32-bit systems, only the lower 32 bits are valid. The above are not used. An implementation of
 /// IAssemblyLinker may not rely on 64-bits being stored in the memory defined by position.
 /// </returns>
 public virtual long Link(LinkType linkType, RuntimeMethod method, int methodOffset, int methodRelativeBase, RuntimeMember target)
 {
     return 0;
 }
Beispiel #16
0
 /// <summary>
 /// Allocates the specified member.
 /// </summary>
 /// <param name="member">The member.</param>
 /// <param name="section">The section.</param>
 /// <param name="size">The size.</param>
 /// <param name="alignment">The alignment.</param>
 /// <returns></returns>
 public virtual Stream Allocate(RuntimeMember member, SectionKind section, int size, int alignment)
 {
     return null;
 }
Beispiel #17
0
        /// <summary>
        /// Allocates memory in the specified section.
        /// </summary>
        /// <param name="member">The metadata member to allocate space for.</param>
        /// <param name="section">The executable section to allocate from.</param>
        /// <param name="size">The number of bytes to allocate. If zero, indicates an unknown amount of memory is required.</param>
        /// <param name="alignment">The alignment. A value of zero indicates the use of a default alignment for the section.</param>
        /// <returns>
        /// A stream, which can be used to populate the section.
        /// </returns>
        public override Stream Allocate(RuntimeMember member, SectionKind section, int size, int alignment)
        {
            string name = CreateSymbolName(member);

            LinkerStream stream = (LinkerStream)base.Allocate(name, section, size, alignment);
            try
            {
                VirtualMemoryStream vms = (VirtualMemoryStream)stream.BaseStream;

                // Save the member address
                member.Address = new IntPtr(vms.Base.ToInt64() + vms.Position);

                LinkerSymbol symbol = this.GetSymbol(name);
                symbol.VirtualAddress = member.Address;
            }
            catch
            {
                stream.Dispose();
                throw;
            }

            return stream;
        }