コード例 #1
0
 /// <summary>
 /// Writes an unsigned byte into the specified .data segment offset.
 /// </summary>
 /// <param name="address">The address in the .data segment to write to.</param>
 /// <param name="value">The value to write to the address.</param>
 public void WriteUnsignedByte(int address, byte value)
 {
     try
     {
         DataSubsection correspondingSubsection = GetDataSegmentForAddress(address);
         int            idx = address - correspondingSubsection.StartingAddress;
         correspondingSubsection.RawData[idx] = value;
     }
     catch (Exception ex) when(ex is ArgumentOutOfRangeException || ex is IndexOutOfRangeException)
     {
         throw new AccessViolationException("Attempted out of bounds 8 bit memory write to address 0x" + address.ToString("X8"));
     }
 }
コード例 #2
0
 /// <summary>
 /// Reads a null-terminated ASCII string from the .data segment.
 /// </summary>
 /// <param name="address">The address in the .data segment to write to.</param>
 /// <param name="value">The value to write to the address.</param>
 public void WriteString(int address, string str)
 {
     try
     {
         DataSubsection correspondingSubsection = GetDataSegmentForAddress(address);
         int            idx      = address - correspondingSubsection.StartingAddress;
         byte[]         strBytes = Encoding.ASCII.GetBytes(str);
         CopyBytes(strBytes, correspondingSubsection.RawData, idx);
     }
     catch (Exception ex) when(ex is ArgumentOutOfRangeException || ex is IndexOutOfRangeException)
     {
         throw new AccessViolationException("Attempted out of bounds memory write to address 0x" + address.ToString("X8"));
     }
 }
コード例 #3
0
 /// <summary>
 /// Writes a 64-bit unsigned integer into the specified .data segment offset.
 /// </summary>
 /// <param name="address">The address in the .data segment to write to.</param>
 /// <param name="value">The value to write to the address.</param>
 public void WriteUnsignedLong(int address, ulong value)
 {
     try
     {
         DataSubsection correspondingSubsection = GetDataSegmentForAddress(address);
         int            idx       = address - correspondingSubsection.StartingAddress;
         byte[]         longBytes = BitConverter.GetBytes(value);
         CopyBytes(longBytes, correspondingSubsection.RawData, idx);
     }
     catch (Exception ex) when(ex is ArgumentOutOfRangeException || ex is IndexOutOfRangeException)
     {
         throw new AccessViolationException("Attempted out of bounds 64 bit memory write to address 0x" + address.ToString("X8"));
     }
 }
コード例 #4
0
        /// <summary>
        /// Simulates an sbrk() syscall. This will allocate the next available word size on the heap memory.
        /// If the requested amount is not word aligned, this will over-allocate to the next word boundary.
        /// </summary>
        /// <param name="amountToAllocate">The number of bytes to allocate.</param>
        /// <returns>The address of the new block, or -1 if the system is out of memory.</returns>
        public int Sbrk(int amountToAllocate)
        {
            int returnAddress = m_CurrHeapAddress;
            int newAddress    = m_CurrHeapAddress + amountToAllocate;

            try
            {
                // get the next word-aligned address.
                if (newAddress % sizeof(int) != 0)
                {
                    newAddress = newAddress + (sizeof(int) - (newAddress % sizeof(int)));
                }

                int            wordAmtToAllocate = amountToAllocate + (sizeof(int) - (amountToAllocate % sizeof(int)));
                DataSubsection subsection        = GetDataSegmentForAddress(m_CurrHeapAddress);

                int currHeapSizeBytes = subsection.RawData.Length;
                int newHeapSize       = currHeapSizeBytes + wordAmtToAllocate;

                // determine if the address is out of our 4MB limit.
                // if so, return -1.
                if (newAddress >= subsection.StartingAddress + InterpreterCommon.MAX_SEGMENT_SIZE)
                {
                    returnAddress = -1;
                }
                else
                {
                    Array.Resize(ref subsection.RawData, newHeapSize);
                    m_CurrHeapAddress = newAddress;
                }
            }
            catch (OutOfMemoryException)
            {
                // if our whole system is legitimately out of memory, return -1. (should never happen).
                // hopefully should be safe, since this is the only area we really dynamically
                // allocate memory during runtime.
                returnAddress = -1;
            }

            return(returnAddress);
        }
コード例 #5
0
        public RuntimeDataSegmentAccessor(DataSegmentAccessor segmentAccessor)
        {
            m_DataSegmentSize = segmentAccessor.SegmentSize;
            m_StartingOffset  = segmentAccessor.BaseRuntimeDataAddress;

            // order data sections from LARGEST to SMALLEST end offset.
            m_DataSubsections = new List <DataSubsection>();

            byte[] stackBytes       = new byte[InterpreterCommon.MAX_SEGMENT_SIZE];
            int    stackBaseOffset  = InterpreterCommon.STACK_BASE_OFFSET;
            int    stackLimitOffset = stackBaseOffset - InterpreterCommon.MAX_SEGMENT_SIZE;

            // since the stack grows downward, need to provide these parameters in reverse order
            DataSubsection stackSubsection = new DataSubsection(stackLimitOffset, stackBaseOffset, stackBytes);

            m_DataSubsections.Add(stackSubsection);

            byte[]         heapBytes       = new byte[0];
            int            heapBaseOffset  = InterpreterCommon.HEAP_BASE_OFFSET;
            int            heapLimitOffset = heapBaseOffset + InterpreterCommon.MAX_SEGMENT_SIZE;
            DataSubsection heapSubsection  = new DataSubsection(heapBaseOffset, heapLimitOffset, heapBytes);

            m_DataSubsections.Add(heapSubsection);

            m_CurrHeapAddress = heapBaseOffset;

            // the heap start overlaps with the static data end, so we may need
            // to reduce this at some point?
            byte[] dataBytes = new byte[InterpreterCommon.MAX_SEGMENT_SIZE];
            Array.Copy(segmentAccessor.RawData.ToArray(), dataBytes, segmentAccessor.RawData.Count());
            int            startingDataOffset = segmentAccessor.BaseRuntimeDataAddress;
            int            limitDataOffset    = startingDataOffset + InterpreterCommon.MAX_SEGMENT_SIZE;
            DataSubsection dataSubsection     = new DataSubsection(startingDataOffset, limitDataOffset, dataBytes);

            m_DataSubsections.Add(dataSubsection);
        }
コード例 #6
0
        /// <summary>
        /// Reads a null-terminated ASCII string from the .data segment.
        /// </summary>
        /// <param name="address">The address to retrieve the string from.</param>
        /// <returns>A string encoded in the ASCII encoding.</returns>
        public string ReadString(int address)
        {
            DataSubsection correspondingSubsection = GetDataSegmentForAddress(address);

            return(DataSegmentCommon.ReadString(correspondingSubsection.RawData, address, correspondingSubsection.StartingAddress));
        }
コード例 #7
0
        /// <summary>
        /// Reads a 32-bit single precision floating point value from the data segment.
        /// </summary>
        /// <param name="address">The address in the .data segment to retrieve the value from.</param>
        /// <returns>The 32-bit floating point value stored at the provided address.</returns>
        public float ReadSinglePrecisionFloat(int address)
        {
            DataSubsection correspondingSubsection = GetDataSegmentForAddress(address);

            return(DataSegmentCommon.ReadSinglePrecisionFloat(correspondingSubsection.RawData, address, correspondingSubsection.StartingAddress));
        }
コード例 #8
0
        /// <summary>
        /// Reads a 32 bit unsigned integer from the data segment.
        /// </summary>
        /// <param name="address">The address in the .data segment to retrieve the value from.</param>
        /// <returns>The 32-bit unsigned integer stored at the provided address.</returns>
        public uint ReadUnsignedWord(int address)
        {
            DataSubsection correspondingSubsection = GetDataSegmentForAddress(address);

            return(DataSegmentCommon.ReadUnsignedWord(correspondingSubsection.RawData, address, correspondingSubsection.StartingAddress));
        }
コード例 #9
0
        /// <summary>
        /// Reads a byte from the data segment.
        /// </summary>
        /// <param name="address">The address in the .data segment to retrieve the byte from.</param>
        /// <returns>The byte stored at the provided address.</returns>
        public sbyte ReadSignedByte(int address)
        {
            DataSubsection correspondingSubsection = GetDataSegmentForAddress(address);

            return(DataSegmentCommon.ReadSignedByte(correspondingSubsection.RawData, address, correspondingSubsection.StartingAddress));
        }