Esempio n. 1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="LinkerStream"/> class.
        /// </summary>
        /// <param name="symbol">The linker symbol created by this stream.</param>
        /// <param name="stream">The stream provided by the actual linker instance.</param>
        /// <param name="length">The length of the symbol. Set to zero, if length is unknown.</param>
        public LinkerStream(LinkerSymbol symbol, Stream stream, long length)
        {
            if (null == symbol)
                throw new ArgumentNullException(@"symbol");
            if (null == stream)
                throw new ArgumentNullException(@"stream");

            this.length = length;
            this.start = stream.Position;
            this.symbol = symbol;
            this.stream = stream;
        }
Esempio n. 2
0
        /// <summary>
        /// Releases the unmanaged resources used by the <see cref="T:System.IO.Stream"/> and optionally releases the managed resources.
        /// </summary>
        /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
        protected override void Dispose(bool disposing)
        {
            if (this.stream != null && this.symbol != null)
            {
                // Fix the linker symbol size
                this.symbol.Length = this.Position;

                // Clear the stream & symbol
                this.stream = null;
                this.symbol = null;
            }

            base.Dispose(disposing);
        }
Esempio n. 3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="LinkerStream"/> class.
        /// </summary>
        /// <param name="symbol">The linker symbol created by this stream.</param>
        /// <param name="stream">The stream provided by the actual linker instance.</param>
        /// <param name="length">The length of the symbol. Set to zero, if length is unknown.</param>
        public LinkerStream(LinkerSymbol symbol, Stream stream, long length)
        {
            if (null == symbol)
            {
                throw new ArgumentNullException("symbol");
            }
            if (null == stream)
            {
                throw new ArgumentNullException("stream");
            }

            this.length = length;
            this.start  = stream.Position;
            this.symbol = symbol;
            this.stream = stream;
        }
Esempio n. 4
0
        /// <summary>
        /// Emits all symbols emitted in the binary file.
        /// </summary>
        /// <param name="linker">The assembly linker.</param>
        private void EmitSymbols(IAssemblyLinker linker)
        {
            this.writer.WriteLine("Offset           Virtual          Length           Symbol");
            foreach (LinkerSymbol symbol in linker.Symbols)
            {
                this.writer.WriteLine("{0:x16} {1:x16} {2:x16} {3}", symbol.Offset, symbol.VirtualAddress.ToInt64(), symbol.Length, symbol.Name);
            }

            LinkerSymbol entryPoint = linker.EntryPoint;

            if (null != entryPoint)
            {
                this.writer.WriteLine();
                this.writer.WriteLine("Entry point is {0}", entryPoint.Name);
                this.writer.WriteLine("\tat offset {0:x16}", entryPoint.Offset);
                this.writer.WriteLine("\tat virtual address {0:x16}", entryPoint.VirtualAddress.ToInt64());
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Allocates a symbol of the given name in the specified section.
        /// </summary>
        /// <param name="name">The name of the symbol.</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(string name, SectionKind section, int size, int alignment)
        {
            Stream stream = Allocate(section, size, alignment);

            try
            {
                // Create a linker symbol for the name
                LinkerSymbol symbol = new LinkerSymbol(name, section, stream.Position);

                // Save the symbol for later use
                _symbols.Add(symbol.Name, symbol);

                // Wrap the stream to catch premature disposal
                stream = new LinkerStream(symbol, stream, size);
            } catch (ArgumentException argx)
            {
                throw new LinkerException(String.Format("Symbol {0} defined multiple times.", name), argx);
            }

            return(stream);
        }
Esempio n. 6
0
        /// <summary>
        /// Releases the unmanaged resources used by the <see cref="T:System.IO.Stream"/> and optionally releases the managed resources.
        /// </summary>
        /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
        protected override void Dispose(bool disposing)
        {
            if (this.stream != null && this.symbol != null)
            {
                // Fix the linker symbol size
                this.symbol.Length = this.Position;

                // Clear the stream & symbol
                this.stream = null;
                this.symbol = null;
            }

            base.Dispose(disposing);
        }
        /// <summary>
        /// Allocates a symbol of the given name in the specified section.
        /// </summary>
        /// <param name="name">The name of the symbol.</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(string name, SectionKind section, int size, int alignment)
        {
            Stream result;
            Stream baseStream = Allocate(section, size, alignment);

            try
            {
                // Create a linker symbol for the name
                LinkerSymbol symbol = new LinkerSymbol(name, section, baseStream.Position);

                // Save the symbol for later use
                _symbols.Add(symbol.Name, symbol);

                // Wrap the stream to catch premature disposal
                result = new LinkerStream(symbol, baseStream, size);
            }
            catch (ArgumentException argx)
            {
                throw new LinkerException(String.Format(@"Symbol {0} defined multiple times.", name), argx);
            }

            return result;
        }
        protected unsafe override void AddVmCalls(IDictionary<string, LinkerSymbol> virtualMachineCalls)
        {
            Trace.WriteLine(@"TestAssemblyLinker adding VM calls:");

            IntPtr allocate = Marshal.GetFunctionPointerForDelegate(this.allocateArrayHandler);

            const string allocateArrayMethod = @"Mosa.Runtime.RuntimeBase.AllocateArray(Ptr methodTable,U4 elementSize,U4 elements)";
            long virtualAddress = allocate.ToInt64();
            Trace.WriteLine(String.Format("\t{0} at 0x{1:x08}", allocateArrayMethod, virtualAddress));

            LinkerSymbol symbol = new LinkerSymbol(allocateArrayMethod, SectionKind.Text, virtualAddress);
            symbol.VirtualAddress = new IntPtr(symbol.SectionAddress);
            virtualMachineCalls.Add(allocateArrayMethod, symbol);

            IntPtr allocateObject = Marshal.GetFunctionPointerForDelegate(this.allocateObjectHandler);

            const string allocateObjectMethod = @"Mosa.Runtime.RuntimeBase.AllocateObject(Ptr methodTable,U4 classSize)";
            virtualAddress = allocateObject.ToInt64();
            Trace.WriteLine(String.Format("\t{0} at 0x{1:x08}", allocateObjectMethod, virtualAddress));

            symbol = new LinkerSymbol(allocateObjectMethod, SectionKind.Text, virtualAddress);
            symbol.VirtualAddress = new IntPtr(symbol.SectionAddress);
            virtualMachineCalls.Add(allocateObjectMethod, symbol);
        }