Beispiel #1
1
        /// <summary>
        /// Process the read/write queues of the specified pipe.
        /// </summary>
        /// <param name="pipe">The pipe to process.</param>
        /// <param name="OutProcess">The process which owns the pipe's outpoint.</param>
        /// <param name="InProcess">The process which owns the pipe's inpoint.</param>
        private static void ProcessPipeQueue(Pipe pipe, Process OutProcess, Process InProcess)
        {
#if PIPES_TRACE
            BasicConsole.WriteLine("ProcessPipeQueue: Checking first loop condition");
#endif
            while ((pipe.AreThreadsWaitingToWrite() && pipe.CanWrite()) || (pipe.AreThreadsWaitingToRead() && pipe.CanRead()))
            {
#if PIPES_TRACE
                BasicConsole.WriteLine("ProcessPipeQueue: Loop start");
#endif
                if (pipe.AreThreadsWaitingToWrite() && pipe.CanWrite())
                {
#if PIPES_TRACE
                    BasicConsole.WriteLine("ProcessPipeQueue: Pipe can write");
#endif

                    /*  - Dequeue thread to write
                     *  - Find thread to write
                     *  - Load pointer to request structure from thread's stack
                     *  - Write pipe
                     *  - Setup return values for thread
                     *  - Wake thread
                     *  - Loop back
                     */

#if PIPES_TRACE
                    BasicConsole.WriteLine("ProcessPipeQueue: Dequeuing out thread id");
#endif
                    UInt32 ThreadId;
                    if (!pipe.DequeueToWrite(out ThreadId))
                    {
                        break;
                    }

#if PIPES_TRACE
                    BasicConsole.WriteLine("ProcessPipeQueue: Getting out thread");
#endif
                    Thread WriteThread = ProcessManager.GetThreadById(ThreadId, OutProcess);
                    if (WriteThread == null)
                    {
                        break;
                    }

#if PIPES_TRACE
                    BasicConsole.WriteLine("ProcessPipeQueue: Writing pipe");
#endif
                    WritePipeRequest* Request = (WritePipeRequest*)WriteThread.Param1;
                    bool Successful = pipe.Write(Request->InBuffer, Request->Offset, Request->Length);
                    if (Successful)
                    {
#if PIPES_TRACE
                        BasicConsole.WriteLine("ProcessPipeQueue: Write successful");
#endif
                        WriteThread.Return1 = (uint)SystemCallResults.OK;
                        WriteThread._Wake();
                    }
                    else
                    {
#if PIPES_TRACE
                        BasicConsole.WriteLine("ProcessPipeQueue: Write failed");
#endif
                        WriteThread.Return1 = (uint)SystemCallResults.Fail;
                        WriteThread._Wake();
                    }
                }
                else if (pipe.AreThreadsWaitingToRead() && pipe.CanRead())
                {
#if PIPES_TRACE
                    BasicConsole.WriteLine("ProcessPipeQueue: Pipe can read");
#endif

                    /*  - Dequeue thread to read
                     *  - Find thread to read
                     *  - Load pointer to request structure from thread's stack
                     *  - Read pipe
                     *  - Setup return values for thread
                     *  - Wake thread
                     *  - Loop back
                    */

#if PIPES_TRACE
                    BasicConsole.WriteLine("ProcessPipeQueue: Dequeuing in thread id");
#endif
                    UInt32 ThreadId;
                    if (!pipe.DequeueToRead(out ThreadId))
                    {
                        break;
                    }

#if PIPES_TRACE
                    BasicConsole.WriteLine("ProcessPipeQueue: Getting in thread");
#endif
                    Thread ReadThread = ProcessManager.GetThreadById(ThreadId, InProcess);
                    if (ReadThread == null)
                    {
                        break;
                    }

#if PIPES_TRACE
                    BasicConsole.WriteLine("ProcessPipeQueue: Reading pipe");
#endif
                    ReadPipeRequest* Request = (ReadPipeRequest*)ReadThread.Param1;
                    int BytesRead;
                    bool Successful = pipe.Read(Request->OutBuffer, Request->Offset, Request->Length, out BytesRead);
                    if (Successful)
                    {
#if PIPES_TRACE
                        BasicConsole.WriteLine("ProcessPipeQueue: Read successful");
#endif
                        ReadThread.Return1 = (uint)SystemCallResults.OK;
                        ReadThread.Return2 = (uint)BytesRead;
                        ReadThread._Wake();
                    }
                    else
                    {
#if PIPES_TRACE
                        BasicConsole.WriteLine("ProcessPipeQueue: Read failed");
#endif
                        ReadThread.Return1 = (uint)SystemCallResults.Fail;
                        ReadThread._Wake();
                    }
                }

#if PIPES_TRACE
                BasicConsole.WriteLine("ProcessPipeQueue: Looping...");
#endif
            }
        }
Beispiel #2
0
        public static void RegisterProcess(Process process, Scheduler.Priority priority)
        {
#if PROCESSMANAGER_TRACE
            BasicConsole.WriteLine("Registering process...");
            BasicConsole.WriteLine("Disabling scheduler...");
#endif
            if (process == null)
            {
                ExceptionMethods.Throw(new FOS_System.Exception("Attempted to register null process!"));
            }

            //bool reenable = Scheduler.Enabled;
            //if (reenable)
            //{
            //    Scheduler.Disable();
            //}
#if PROCESSMANAGER_TRACE
            BasicConsole.WriteLine("Initialising process...");
#endif
            Scheduler.InitProcess(process, priority);

#if PROCESSMANAGER_TRACE
            BasicConsole.WriteLine("Adding process...");
#endif

            Processes.Add(process);

#if PROCESSMANAGER_TRACE
            BasicConsole.WriteLine("Enabling scheduler...");
#endif
            //if (reenable)
            //{
            //    Scheduler.Enable();
            //}
        }
Beispiel #3
0
        public static void InitThread(Process process, Thread t)
        {
            t.TimeToRunReload = (int)process.Priority;
            t.TimeToRun = t.TimeToRunReload;

            UpdateList(t, false);
        }
Beispiel #4
0
 public static MemoryLayout EnableAccessToMemoryOfProcess(Process ProcessToAccess)
 {
     MemoryLayout OriginalMemoryLayout = ProcessManager.CurrentProcess.TheMemoryLayout;
     MemoryLayout NewMemoryLayout = ProcessManager.CurrentProcess.TheMemoryLayout.Merge(ProcessToAccess.TheMemoryLayout);
     ProcessManager.CurrentProcess.TheMemoryLayout = NewMemoryLayout;
     NewMemoryLayout.Load(ProcessManager.CurrentProcess.UserMode);
     return OriginalMemoryLayout;
 }
Beispiel #5
0
        //private static int LockupCounter = 0;

        public static void InitProcess(Process process, Priority priority)
        {
            process.Priority = priority;
            
            for (int i = 0; i < process.Threads.Count; i++)
            {
                Thread t = (Thread)process.Threads[i];

                InitThread(process, t);
            }

            process.Registered = true;
        }
Beispiel #6
0
 public static Thread GetThreadById(uint threadId, Process parent)
 {
     for (int i = 0; i < parent.Threads.Count; i++)
     {
         if (((Thread)parent.Threads[i]).Id == threadId)
         {
             return (Thread)parent.Threads[i];
         }
     }
     return null;
 }
Beispiel #7
0
        public static unsafe SystemCallResults HandleDeferredSystemCall(
            Process CallerProcess, Thread CallerThread,
            SystemCallNumbers syscallNumber, uint Param1, uint Param2, uint Param3,
            ref uint Return2, ref uint Return3, ref uint Return4)
        {
            SystemCallResults result = SystemCallResults.Unhandled;

            switch (syscallNumber)
            {
                case SystemCallNumbers.StartThread:
                    //BasicConsole.WriteLine("DSC: Start Thread");
                    Return2 = CallerProcess.CreateThread((ThreadStartMethod)Utilities.ObjectUtilities.GetObject((void*)Param1), "[From sys call]").Id;
                    //BasicConsole.WriteLine("DSC: Start Thread - done.");
                    result = SystemCallResults.OK;
                    break;
                case SystemCallNumbers.RegisterPipeOutpoint:
                    {
                        //BasicConsole.WriteLine("DSC: Register Pipe Outpoint");
                        Pipes.PipeOutpoint outpoint;
                        bool registered = Pipes.PipeManager.RegisterPipeOutpoint(CallerProcess.Id, (Pipes.PipeClasses)Param1, (Pipes.PipeSubclasses)Param2, (int)Param3, out outpoint);
                        if (registered)
                        {
                            result = SystemCallResults.OK;
                        }
                        else
                        {
                            result = SystemCallResults.Fail;
                        }
                        //BasicConsole.WriteLine("DSC: Register Pipe Outpoint - done.");
                    }
                    break;
                case SystemCallNumbers.GetNumPipeOutpoints:
                    {
                        //BasicConsole.WriteLine("DSC: Get Num Pipe Outpoints");
                        int numOutpoints;
                        bool obtained = Pipes.PipeManager.GetNumPipeOutpoints((Pipes.PipeClasses)Param1, (Pipes.PipeSubclasses)Param2, out numOutpoints);
                        if (obtained)
                        {
                            result = SystemCallResults.OK;
                            Return2 = (uint)numOutpoints;
                        }
                        else
                        {
                            result = SystemCallResults.Fail;
                        }
                        //BasicConsole.WriteLine("DSC: Get Num Pipe Outpoints - done");
                    }
                    break;
                case SystemCallNumbers.GetPipeOutpoints:
                    {
                        //BasicConsole.WriteLine("DSC: Get Pipe Outpoints");
                        
                        bool obtained = Pipes.PipeManager.GetPipeOutpoints(CallerProcess, (Pipes.PipeClasses)Param1, (Pipes.PipeSubclasses)Param2, (Pipes.PipeOutpointsRequest*)Param3);
                        if (obtained)
                        {
                            result = SystemCallResults.OK;
                        }
                        else
                        {
                            result = SystemCallResults.Fail;
                        }
                        
                        //BasicConsole.WriteLine("DSC: Get Pipe Outpoints - done");
                    }
                    break;
                case SystemCallNumbers.CreatePipe:
                    {
                        //BasicConsole.WriteLine("DSC: Create Pipe");

                        bool created = Pipes.PipeManager.CreatePipe(CallerProcess.Id, Param1, (Pipes.CreatePipeRequest*)Param2);
                        if (created)
                        {
                            result = SystemCallResults.OK;
                        }
                        else
                        {
                            result = SystemCallResults.Fail;
                        }

                        //BasicConsole.WriteLine("DSC: Create Pipe - done");
                    }
                    break;
                case SystemCallNumbers.WaitOnPipeCreate:
                    {
                        //BasicConsole.WriteLine("DSC: Wait On Pipe Create");

                        bool waiting = Pipes.PipeManager.WaitOnPipeCreate(CallerProcess.Id, CallerThread.Id, (Pipes.PipeClasses)Param1, (Pipes.PipeSubclasses)Param2);
                        if (waiting)
                        {
                            result = SystemCallResults.Deferred;
                        }
                        else
                        {
                            result = SystemCallResults.Fail;
                        }

                        //BasicConsole.WriteLine("DSC: Wait On Pipe Create - done");
                    }
                    break;
                case SystemCallNumbers.ReadPipe:
                    {
                        //BasicConsole.WriteLine("DSC: Read Pipe");

                        // Need access to calling process' memory to be able to set values in request structure(s)
                        MemoryLayout OriginalMemoryLayout = SystemCallsHelpers.EnableAccessToMemoryOfProcess(CallerProcess);

                        Pipes.ReadPipeRequest* RequestPtr = (Pipes.ReadPipeRequest*)Param1;
                        Pipes.PipeManager.RWResults RWResult = Pipes.PipeManager.ReadPipe(RequestPtr->PipeId, RequestPtr->Blocking, CallerProcess, CallerThread);

                        if (RWResult == Pipes.PipeManager.RWResults.Error)
                        {
                            result = SystemCallResults.Fail;
                        }
                        else
                        {
                            // Returning Deferred state from here will leave the caller thread
                            //  in whatever state ReadPipe decided it should be in.
                            result = SystemCallResults.Deferred;
                        }
                        
                        SystemCallsHelpers.DisableAccessToMemoryOfProcess(OriginalMemoryLayout);

                        //BasicConsole.WriteLine("DSC: Read Pipe - done");
                    }
                    break;
                case SystemCallNumbers.WritePipe:
                    {
                        //BasicConsole.WriteLine("DSC: Write Pipe");

                        // Need access to calling process' memory to be able to set values in request structure(s)
                        MemoryLayout OriginalMemoryLayout = SystemCallsHelpers.EnableAccessToMemoryOfProcess(CallerProcess);

                        Pipes.WritePipeRequest* RequestPtr = (Pipes.WritePipeRequest*)Param1;
                        Pipes.PipeManager.RWResults RWResult = Pipes.PipeManager.WritePipe(RequestPtr->PipeId, RequestPtr->Blocking, CallerProcess, CallerThread);

                        if (RWResult == Pipes.PipeManager.RWResults.Error)
                        {
                            result = SystemCallResults.Fail;
                        }
                        else
                        {
                            // Returning Deferred state from here will leave the caller thread
                            //  in whatever state WritePipe decided it should be in.
                            result = SystemCallResults.Deferred;
                        }
                        
                        SystemCallsHelpers.DisableAccessToMemoryOfProcess(OriginalMemoryLayout);

                        //BasicConsole.WriteLine("DSC: Write Pipe - done");
                    }
                    break;
                default:
                    BasicConsole.WriteLine("DSC: Unrecognised call number.");
                    BasicConsole.WriteLine((uint)syscallNumber);
                    break;
            }

            return result;
        }
Beispiel #8
0
        /// <remarks>
        /// Specifying threadId=-1 accepts any thread from the specified process.
        /// No guarantees are made about the thread chosen. This is used when you
        /// mainly want to switch process context and don't care about the specific
        /// thread context e.g. during an interrupt.
        /// </remarks>
        public static void SwitchProcess(uint processId, int threadId)
        {
            //Switch the current memory layout across.
            //  Don't touch register state etc, just the memory layout

            bool dontSwitchOutIn = false;

            if (CurrentProcess != null &&
                CurrentProcess.Id == processId)
            {
                if (CurrentThread != null &&
                    (CurrentThread.Id == threadId || threadId == -1))
                {
#if PROCESSMANAGER_SWITCH_TRACE
                    BasicConsole.WriteLine("No switch. (1)");
#endif
                    return;
                }
                else
                {
#if PROCESSMANAGER_SWITCH_TRACE
                    BasicConsole.WriteLine("No switch. (2)");
#endif
                    dontSwitchOutIn = true;
                }
            }

            if (!dontSwitchOutIn)
            {
#if PROCESSMANAGER_SWITCH_TRACE
                BasicConsole.WriteLine("Switching out: " + CurrentProcess.Name);
#endif
                CurrentProcess.UnloadMemLayout();

                CurrentProcess = null;
                
                for (int i = 0; i < Processes.Count; i++)
                {
                    if (((Process)Processes[i]).Id == processId)
                    {
                        CurrentProcess = ((Process)Processes[i]);
                        break;
                    }
                }

                // Process not found
                if (CurrentProcess == null)
                {
#if PROCESSMANAGER_SWITCH_TRACE
                    BasicConsole.WriteLine("Process not found.");
#endif
                    return;
                }
#if PROCESSMANAGER_SWITCH_TRACE
                BasicConsole.WriteLine("Process found. " + CurrentProcess.Name);
#endif
            }

            CurrentThread = null;
            CurrentThread_State = null;

            if (threadId == -1)
            {
                if (CurrentProcess.Threads.Count > 0)
                {
                    CurrentThread = (Thread)CurrentProcess.Threads[0];
                }
            }
            else
            {
                for (int i = 0; i < CurrentProcess.Threads.Count; i++)
                {
                    if (((Thread)CurrentProcess.Threads[i]).Id == threadId)
                    {
                        CurrentThread = (Thread)CurrentProcess.Threads[i];
                        break;
                    }
                }
            }

            // No threads in the process (?!) or process not found
            if (CurrentThread == null)
            {
#if PROCESSMANAGER_SWITCH_TRACE
                BasicConsole.WriteLine("Thread not found.");
#endif
                return;
            }
#if PROCESSMANAGER_SWITCH_TRACE
            BasicConsole.WriteLine("Thread found.");
#endif

            CurrentThread_State = CurrentThread.State;
#if PROCESSMANAGER_SWITCH_TRACE
            BasicConsole.WriteLine("Thread state updated.");
#endif
            
            if (!dontSwitchOutIn)
            {
#if PROCESSMANAGER_SWITCH_TRACE
                BasicConsole.WriteLine("Switching in: " + CurrentProcess.Name);
#endif
                CurrentProcess.LoadMemLayout();
            }
        }
Beispiel #9
0
 public static bool Semaphore_AddOwner(int semaphoreId, uint processId, Process aProcess)
 {
     if (Semaphore_VerifyOwner(semaphoreId, aProcess))
     {
         ((Semaphore)Semaphores[semaphoreId]).OwnerProcesses.Add(processId);
         return true;
     }
     return false;
 }
Beispiel #10
0
        public Thread(Process AnOwner, ThreadStartMethod StartMethod, uint AnId, bool UserMode, FOS_System.String AName)
        {
#if THREAD_TRACE
            BasicConsole.WriteLine("Constructing thread object...");
#endif
            LastActiveState = ActiveStates.NotStarted;
            Owner = AnOwner;

            //Init thread state
            #if THREAD_TRACE
            BasicConsole.WriteLine("Allocating state memory...");
#endif
            State = (ThreadState*)FOS_System.Heap.Alloc((uint)sizeof(ThreadState), "Thread : Thread() (1)");

            // Init Id and EIP
            //  Set EIP to the first instruction of the main method
#if THREAD_TRACE
            BasicConsole.WriteLine("Setting thread info...");
#endif
            Id = AnId;
            Name = AName;
            State->StartEIP = (uint)Utilities.ObjectUtilities.GetHandle(StartMethod);

            // Allocate kernel memory for the kernel stack for this thread
            //  Used when this thread is preempted or does a sys call. Stack is switched to
            //  this thread-specific kernel stack
#if THREAD_TRACE
            BasicConsole.WriteLine("Allocating kernel stack...");
#endif
            // TODO: Allocate using virt mem manager not the heap (see ThreadStackTop below)
            State->KernelStackTop = (byte*)FOS_System.Heap.Alloc(0x1000, 4) + 0xFFC; //4KiB, 4-byte aligned
            
            // Allocate free memory for the user stack for this thread
            //  Used by this thread in normal execution
#if THREAD_TRACE
            BasicConsole.WriteLine("Mapping thread stack page...");
#endif
            State->UserMode = UserMode;
            State->ThreadStackTop = (byte*)Hardware.VirtMemManager.MapFreePage(
                UserMode ? Hardware.VirtMem.VirtMemImpl.PageFlags.None :
                           Hardware.VirtMem.VirtMemImpl.PageFlags.KernelOnly) + 4092; //4 KiB, page-aligned
            
            // Set ESP to the top of the stack - 4 byte aligned, high address since x86 stack works
            //  downwards
#if THREAD_TRACE
            BasicConsole.WriteLine("Setting ESP...");
#endif
            State->ESP = (uint)State->ThreadStackTop;

            // TimeToRun and TimeToRunReload are set up in Scheduler.InitProcess which
            //      is called when a process is registered.

            // Init SS
            //  Stack Segment = User or Kernel space data segment selector offset
            //  Kernel data segment selector offset (offset in GDT) = 0x10 (16)
            //  User   data segment selector offset (offset in GDT) = 0x23 (32|3)
            //          User data segment selector must also be or'ed with 3 for User Privilege level
#if THREAD_TRACE
            BasicConsole.WriteLine("Setting SS...");
#endif
            State->SS = UserMode ? (ushort)0x23 : (ushort)0x10;

            // Init Started
            //  Not started yet so set to false
#if THREAD_TRACE
            BasicConsole.WriteLine("Setting started...");
#endif
            State->Started = false;

#if THREAD_TRACE
            BasicConsole.WriteLine("Allocating exception state...");
#endif
            //TODO: This is currently incorrectly allocated from the current process's heap instead of the heap of the owner process
            // Init Exception State
            State->ExState = (ExceptionState*)FOS_System.Heap.AllocZeroed((uint)sizeof(ExceptionState), "Thread : Thread() (2)");

#if THREAD_TRACE
            BasicConsole.WriteLine("Done.");
#endif
        }
Beispiel #11
0
        public static int Semaphore_Allocate(int limit, Process aProcess)
        {
            int result = -1;
            Semaphore theSemaphore = null;

            SemaphoresLock.Enter();

            for (int i = 0; i < Semaphores.Count; i++)
            {
                Semaphore aSemaphore = (Semaphore)Semaphores[i];
                if (aSemaphore == null)
                {
                    Semaphores[i] = theSemaphore = new Semaphore(i, limit);
                    result = i;
                    break;
                }
            }

            if (result == -1)
            {
                result = Semaphores.Count;
                Semaphores.Add(theSemaphore = new Semaphore(result, limit));
            }

            SemaphoresLock.Exit();

            theSemaphore.OwnerProcesses.Add(aProcess.Id);

            return result;
        }
Beispiel #12
0
 public static int Semaphore_Wait(int id, Process aProcess, Thread aThread)
 {
     if (Semaphore_VerifyOwner(id, aProcess))
     {
         return ((Semaphore)Semaphores[id]).WaitOnBehalf(aProcess, aThread) ? 1 : 0;
     }
     return -1;
 }
Beispiel #13
0
        public static void SwitchProcess(uint processId, int threadId)
        {
            //Switch the current memory layout across.
            //  Don't touch register state etc, just the memory layout

            bool dontSwitchOutIn = false;

            if (CurrentProcess != null &&
                CurrentProcess.Id == processId)
            {
                if (CurrentThread != null &&
                    (CurrentThread.Id == threadId || threadId == THREAD_DONT_CARE))
                {
#if PROCESSMANAGER_SWITCH_TRACE
                    BasicConsole.WriteLine("No switch. (1)");
#endif
                    return;
                }
                else
                {
#if PROCESSMANAGER_SWITCH_TRACE
                    BasicConsole.WriteLine("No switch. (2)");
#endif
                    dontSwitchOutIn = true;
                }
            }

            if (!dontSwitchOutIn)
            {
#if PROCESSMANAGER_SWITCH_TRACE
                BasicConsole.Write("Switching out: ");
                BasicConsole.WriteLine(CurrentProcess.Name);
#endif
                CurrentProcess.UnloadHeap();
                CurrentProcess.UnloadMemLayout();

                CurrentProcess = GetProcessById(processId);

                // Process not found
                if (CurrentProcess == null)
                {
#if PROCESSMANAGER_SWITCH_TRACE
                    BasicConsole.WriteLine("Process not found.");
#endif
                    return;
                }

#if PROCESSMANAGER_SWITCH_TRACE
                BasicConsole.Write("Switching in: ");
                BasicConsole.WriteLine(CurrentProcess.Name);
#endif
                CurrentProcess.LoadMemLayout();
                CurrentProcess.LoadHeap();
            }

            CurrentThread = null;
            CurrentThread_State = null;

            if (threadId == THREAD_DONT_CARE)
            {
                if (CurrentProcess.Threads.Count > 0)
                {
                    CurrentThread = (Thread)CurrentProcess.Threads[0];
                }
            }
            else
            {
                CurrentThread = GetThreadById((uint)threadId, CurrentProcess);
            }

            // No threads in the process (?!) or process not found
            if (CurrentThread == null)
            {
#if PROCESSMANAGER_SWITCH_TRACE
                BasicConsole.WriteLine("Thread not found.");
#endif
                return;
            }
#if PROCESSMANAGER_SWITCH_TRACE
            BasicConsole.WriteLine("Thread found.");
#endif

            CurrentThread_State = CurrentThread.State;
#if PROCESSMANAGER_SWITCH_TRACE
            BasicConsole.WriteLine("Thread state updated.");
#endif
        }
Beispiel #14
0
        /// <summary>
        /// Attempts to write to the specified pipe.
        /// </summary>
        /// <remarks>
        /// Note that this function is non-blocking. It will, however, block a system caller thread by simply not returning it from
        /// the deferred system call.
        /// </remarks>
        /// <param name="PipeId">The Id of the pipe to write.</param>
        /// <param name="Blocking">Whether the write should be blocking or non-blocking.</param>
        /// <param name="CallerProcess">The process which made the call.</param>
        /// <param name="CallerThread">The thread which made the call.</param>
        /// <returns>See descriptions on <see cref="PipeManager.RWResults"/> values.</returns>
        public static RWResults WritePipe(int PipeId, bool Blocking, Process CallerProcess, Thread CallerThread)
        {
#if PIPES_TRACE
            BasicConsole.WriteLine("WritePipe: Validating inputs");
#endif
            // Validate inputs
            //  - Check pipe exists
            Pipe pipe = GetPipe(PipeId);
            if (pipe == null)
            {
                return RWResults.Error;
            }

#if PIPES_TRACE
            BasicConsole.WriteLine("WritePipe: Checking caller allowed to write");
#endif
            // Check the caller is allowed to access the pipe
            if (!AllowedToWritePipe(pipe, CallerProcess.Id))
            {
                return RWResults.Error;
            }

#if PIPES_TRACE
            BasicConsole.WriteLine("WritePipe: Getting out process");
#endif
            // Get outpoint process
            Process OutProcess = ProcessManager.GetProcessById(pipe.Outpoint.ProcessId);
            if (OutProcess == null)
            {
                return RWResults.Error;
            }

#if PIPES_TRACE
            BasicConsole.WriteLine("WritePipe: Getting in process");
#endif
            // Get inpoint process
            Process InProcess = ProcessManager.GetProcessById(pipe.Inpoint.ProcessId);
            if (InProcess == null)
            {
                return RWResults.Error;
            }

#if PIPES_TRACE
            BasicConsole.WriteLine("WritePipe: Merging memory layouts");
#endif
            // Merge memory layouts of in process (out process should already have been done by caller)
            //  so we can access the request structure(s) and buffers
            MemoryLayout OriginalMemoryLayout = SystemCallsHelpers.EnableAccessToMemoryOfProcess(InProcess);

#if PIPES_TRACE
            BasicConsole.WriteLine("WritePipe: Adding caller to write queue");
#endif
            // Add caller thread to the write queue
            WritePipeRequest* Request = (WritePipeRequest*)CallerThread.Param1;
            pipe.QueueToWrite(CallerThread.Id, Request->Length);

            // Set up initial failure return value
            CallerThread.Return1 = (uint)SystemCallResults.Fail;

#if PIPES_TRACE
            BasicConsole.WriteLine("WritePipe: Processing pipe queue");
#endif
            // Process the pipe queue
            ProcessPipeQueue(pipe, OutProcess, InProcess);

#if PIPES_TRACE
            BasicConsole.WriteLine("WritePipe: Unmerging memory layouts");
#endif
            // Unmerge memory layouts
            SystemCallsHelpers.DisableAccessToMemoryOfProcess(OriginalMemoryLayout);

            bool Completed = !pipe.AreThreadsWaitingToWrite();
            if (!Blocking)
            {
                if (!Completed)
                {
                    uint temp;
                    bool removed = pipe.RemoveLastToWrite(out temp);

                    if (!removed || temp != CallerThread.Id)
                    {
                        BasicConsole.WriteLine("PipeManager: Error! Async write failed and then removing last from queue resulted in thread Id mismatch!");
                    }

                    CallerThread.Return1 = (uint)SystemCallResults.Fail;
                    CallerThread._Wake();
                }
            }
            return Completed ? RWResults.Complete : RWResults.Queued;
        }
Beispiel #15
0
        /// <summary>
        /// Attempts to get descriptors of the outpoints of the specified class and subclass.
        /// </summary>
        /// <param name="CallerProcess">The process which owns the memory containing the <paramref cref="request"/>.</param>
        /// <param name="Class">The class of outpoint to search for.</param>
        /// <param name="Subclass">The subclass of outpoint to search for.</param>
        /// <param name="request">A pointer to the request structure (Also used to store the result(s)).</param>
        /// <returns>True if the request was successful. Otherwise, false.</returns>
        public static bool GetPipeOutpoints(Process CallerProcess, PipeClasses Class, PipeSubclasses Subclass, PipeOutpointsRequest* request)
        {
            // Validate inputs & get caller process
            if (CallerProcess == null)
            {
                return false;
            }

            // Merge memory layouts 
            //  so we can access the request structure
            MemoryLayout OriginalMemoryLayout = SystemCallsHelpers.EnableAccessToMemoryOfProcess(CallerProcess);
            bool OK = true;

            // More validate inputs
            //  - Check request exists (should've been pre-allocated by caller)
            //  - Check request->Outpoints exists (should've been pre-allocated by caller)
            //  - Check request->MaxDescriptors was set correctly
            if (request == null)
            {
                // Should have been pre-allocated by the calling thread (/process)
                OK = false;
            }
            else if (request->Outpoints == null)
            {
                // Should have been pre-allocated by the calling thread (/process)
                OK = false;
            }
            else if (request->MaxDescriptors == 0)
            {
                // Not technically an error but let's not waste time processing 0 descriptors
                OK = true;
            }

            if (OK)
            {
                // Search for all outpoints of correct class and subclass
                int maxDescriptors = request->MaxDescriptors;
                for (int i = 0, j = 0; i < PipeOutpoints.Count && j < maxDescriptors; i++)
                {
                    PipeOutpoint anOutpoint = (PipeOutpoint)PipeOutpoints[i];

                    if (anOutpoint.Class == Class &&
                        anOutpoint.Subclass == Subclass &&
                        (   anOutpoint.MaxConnections == PipeConstants.UnlimitedConnections ||
                            anOutpoint.NumConnections < anOutpoint.MaxConnections))
                    {
                        // Set the resultant values
                        request->Outpoints[j++].ProcessId = anOutpoint.ProcessId;
                    }
                }
            }

            SystemCallsHelpers.DisableAccessToMemoryOfProcess(OriginalMemoryLayout);

            return OK;
        }
Beispiel #16
0
        public static void DisableKernelAccessToProcessMemory(Process TargetProcess)
        {
            if (KernelProcess != null && KernelProcess != TargetProcess)
            {
#if PROCESSMANAGER_KERNEL_ACCESS_TRACE
                BasicConsole.WriteLine("~D~");
#endif

                KernelProcess.TheMemoryLayout.Unmerge(TargetProcess.TheMemoryLayout);
                TargetProcess.TheMemoryLayout.Unload();
            }
        }
Beispiel #17
0
        public static void EnableKernelAccessToProcessMemory(Process TargetProcess)
        {
            if (KernelProcess != null && KernelProcess != TargetProcess)
            {
#if PROCESSMANAGER_KERNEL_ACCESS_TRACE
                BasicConsole.WriteLine("~E~");
#endif

                KernelProcess.TheMemoryLayout.Merge(TargetProcess.TheMemoryLayout);
                KernelProcess.TheMemoryLayout.Load(KernelProcess.UserMode);
            }
        }
Beispiel #18
0
        public static bool WakeThread(Process theProcess, uint threadId)
        {
            bool Woken = false;

            if (theProcess != null)
            {
                Thread theThread = GetThreadById(threadId, theProcess);
                if (theThread != null)
                {
                    theThread._Wake();
                    Woken = true;
                }
            }

            return Woken;
        }
Beispiel #19
0
 public static void InitProcess(Process process, Priority priority)
 {
     process.Priority = priority;
 }
Beispiel #20
0
        public static bool Semaphore_Deallocate(int id, Process aProcess)
        {
            if (Semaphore_VerifyOwner(id, aProcess))
            {
                SemaphoresLock.Enter();
                Semaphores[id] = null;
                SemaphoresLock.Exit();

                return true;
            }
            return false;
        }
Beispiel #21
0
 public static void EndDeferredSystemCall(Process CallerProcess, Thread CallerThread, SystemCallResults result, uint Return2, uint Return3, uint Return4)
 {
     ProcessManager.EnableKernelAccessToProcessMemory(CallerProcess);
     CallerThread.Return1 = (uint)result;
     CallerThread.Return2 = Return2;
     CallerThread.Return3 = Return3;
     CallerThread.Return4 = Return4;
     ProcessManager.DisableKernelAccessToProcessMemory(CallerProcess);
     
     CallerThread._Wake();
 }
Beispiel #22
0
 public static bool Semaphore_Signal(int id, Process aProcess)
 {
     if (Semaphore_VerifyOwner(id, aProcess))
     {
         ((Semaphore)Semaphores[id]).SignalOnBehalf();
         return true;
     }
     return false;
 }
Beispiel #23
0
        public void Load(bool UserMode)
        {
            bool OK = true;
            
            try
            {
                bool DynamicLinkingRequired = false;

                ThreadStartMethod mainMethod = (ThreadStartMethod)Utilities.ObjectUtilities.GetObject(theFile.Header.EntryPoint);
                theProcess = ProcessManager.CreateProcess(
                    mainMethod, theFile.TheFile.Name, UserMode);

                uint threadStackVirtAddr = (uint)((Thread)theProcess.Threads[0]).State->ThreadStackTop - 4092;
                uint threadStackPhysAddr = (uint)Hardware.VirtMemManager.GetPhysicalAddress(threadStackVirtAddr);
                ProcessManager.CurrentProcess.TheMemoryLayout.AddDataPage(threadStackPhysAddr, threadStackVirtAddr);
                
                // Load the ELF segments (i.e. the program code and data)
                BaseAddress = theFile.BaseAddress;
                LoadSegments(theFile, ref OK, ref DynamicLinkingRequired, BaseAddress);

                //BasicConsole.WriteLine();
                
                #region Relocations

                // Useful articles / specifications on Relocations:
                //      - Useful / practical explanation of various relocation types: http://eli.thegreenplace.net/2011/08/25/load-time-relocation-of-shared-libraries/#id20
                //      - Orcale : ELF Specification copy: http://docs.oracle.com/cd/E23824_01/html/819-0690/chapter6-54839.html
                
                if (DynamicLinkingRequired)
                {
                    Console.Default.WriteLine("Dynamic Linking");
                    BasicConsole.WriteLine("Dynamic Linking");

                    ELFDynamicSection dynamicSection = theFile.DynamicSection;
                    ELFDynamicSymbolTableSection dynamicSymbolsSection = theFile.DynamicSymbolsSection;

                    ELFStringTable DynamicsStringTable = new ELFStringTable(
                        dynamicSection.StrTabDynamic.Val_Ptr, dynamicSection.StrTabSizeDynamic.Val_Ptr);

                    for (uint i = 0; i < dynamicSection.Dynamics.Count; i++)
                    {
                        ELFDynamicSection.Dynamic theDyn = dynamicSection[i];

                        //BasicConsole.WriteLine("     - Dynamic : ");
                        //BasicConsole.Write("         - Tag : ");
                        //BasicConsole.WriteLine((int)theDyn.Tag);
                        //BasicConsole.Write("         - Value or Pointer : ");
                        //BasicConsole.WriteLine(theDyn.Val_Ptr);

                        if (theDyn.Tag == ELFDynamicSection.DynamicTag.Needed)
                        {
                            BasicConsole.Write("         - Needed library name : ");

                            FOS_System.String libFullPath = DynamicsStringTable[theDyn.Val_Ptr];
                            Console.Default.WriteLine(libFullPath);
                            BasicConsole.WriteLine(libFullPath);

                            FOS_System.String libFileName = (FOS_System.String)libFullPath.Split('\\').Last();
                            libFileName = (FOS_System.String)libFileName.Split('/').Last();
                            FOS_System.String libTestPath = theFile.TheFile.Parent.GetFullPath() + libFileName;
                            File sharedObjectFile = File.Open(libTestPath);
                            if (sharedObjectFile == null)
                            {
                                Console.Default.WarningColour();
                                Console.Default.WriteLine("Failed to find needed library file!");
                                BasicConsole.WriteLine("Failed to find needed library file!");
                                Console.Default.DefaultColour();
                                OK = false;
                            }
                            else
                            {
                                Console.Default.WriteLine("Found library file. Loading library...");
                                BasicConsole.WriteLine("Found library file. Loading library...");

                                ELFSharedObject sharedObject = DynamicLinkerLoader.LoadLibrary_FromELFSO(sharedObjectFile, this);
                                SharedObjectDependencies.Add(sharedObject);

                                Console.Default.WriteLine("Library loaded.");
                                BasicConsole.WriteLine("Library loaded.");
                            }
                        }
                    }

                    Console.Default.WriteLine("Library Relocations");
                    BasicConsole.WriteLine("Library Relocations");

                    // Perform relocation / dynamic linking of all libraries
                    for (int i = 0; i < SharedObjectDependencies.Count; i++)
                    {
                        ELFSharedObject SO = (ELFSharedObject)SharedObjectDependencies[i];

                        //BasicConsole.WriteLine("Shared Object base address : " + (FOS_System.String)SO.BaseAddress);
                        //BasicConsole.WriteLine("Shared Object file base address : " + (FOS_System.String)SO.TheFile.BaseAddress);
                        
                        List SOSections = SO.TheFile.Sections;
                        for (int j = 0; j < SOSections.Count; j++)
                        {
                            ELFSection SOSection = (ELFSection)SOSections[j];
                            if (SOSection is ELFRelocationTableSection)
                            {
                                //BasicConsole.WriteLine(" - Normal Relocation");

                                ELFRelocationTableSection relocTableSection = (ELFRelocationTableSection)SOSection;
                                ELFSymbolTableSection symbolTable = (ELFSymbolTableSection)SO.TheFile.Sections[relocTableSection.SymbolTableSectionIndex];
                                ELFStringTableSection symbolNamesTable = (ELFStringTableSection)SO.TheFile.Sections[symbolTable.StringsSectionIndex];

                                List Relocations = relocTableSection.Relocations;
                                for (int k = 0; k < Relocations.Count; k++)
                                {
                                    // Reference: http://docs.oracle.com/cd/E19683-01/817-3677/chapter6-26/index.html

                                    ELFRelocationTableSection.Relocation relocation = (ELFRelocationTableSection.Relocation)Relocations[k];
                                    if (relocation.Type == ELFRelocationTableSection.RelocationType.R_386_NONE)
                                    {
                                        continue;
                                    }

                                    uint* resolvedRelLocation = (uint*)(SO.BaseAddress + (relocation.Offset - SO.TheFile.BaseAddress));
                                    ELFSymbolTableSection.Symbol symbol = (ELFSymbolTableSection.Symbol)symbolTable[relocation.Symbol];
                                    FOS_System.String symbolName = symbolNamesTable[symbol.NameIdx];

                                    //BasicConsole.WriteLine("Relocation:");
                                    ////BasicConsole.WriteLine("    > Symbol index : " + (FOS_System.String)relocation.Symbol);
                                    //BasicConsole.WriteLine("    > Type : " + (FOS_System.String)(uint)relocation.Type);
                                    //BasicConsole.WriteLine("    > Offset : " + (FOS_System.String)(uint)relocation.Offset);
                                    //BasicConsole.WriteLine(((FOS_System.String)"    > Resolved location address: ") + (uint)resolvedRelLocation);
                                    ////BasicConsole.WriteLine(((FOS_System.String)"    > Resolved location start value: ") + *resolvedRelLocation);
                                    //BasicConsole.Write("    > Symbol name : ");
                                    //BasicConsole.WriteLine(symbolName);

                                    uint newValue = 0;
                                    switch (relocation.Type)
                                    {
                                        case ELFRelocationTableSection.RelocationType.R_386_32:
                                            newValue = GetSymbolAddress(symbol, symbolName) + *resolvedRelLocation;
                                            break;
                                        case ELFRelocationTableSection.RelocationType.R_386_PC32:
                                            newValue = GetSymbolAddress(symbol, symbolName) + *resolvedRelLocation - (uint)resolvedRelLocation;
                                            break;
                                        case ELFRelocationTableSection.RelocationType.R_386_RELATIVE:
                                            newValue = SO.BaseAddress + *resolvedRelLocation;
                                            break;
                                        //TODO: Support more relocation types
                                        default:
                                            Console.Default.WarningColour();
                                            Console.Default.Write("WARNING: Unrecognised relocation type! (");
                                            Console.Default.Write_AsDecimal((uint)relocation.Type);
                                            Console.Default.WriteLine(")");
                                            Console.Default.DefaultColour();

                                            BasicConsole.Write("WARNING: Unrecognised relocation type! (");
                                            BasicConsole.Write((uint)relocation.Type);
                                            BasicConsole.WriteLine(")");
                                            break;
                                    }

                                    *resolvedRelLocation = newValue;

                                    //BasicConsole.WriteLine("    > New value: " + (FOS_System.String)(newValue));
                                    //BasicConsole.WriteLine("    > Resolved location end value: " + (FOS_System.String)(*resolvedRelLocation));

                                }
                            }
                            else if (SOSection is ELFRelocationAddendTableSection)
                            {
                                //BasicConsole.WriteLine(" - Addend Relocation");

                                ELFRelocationAddendTableSection relocTableSection = (ELFRelocationAddendTableSection)SOSection;
                                ELFSymbolTableSection symbolTable = (ELFSymbolTableSection)SO.TheFile.Sections[relocTableSection.SymbolTableSectionIndex];
                                ELFStringTableSection symbolNamesTable = (ELFStringTableSection)SO.TheFile.Sections[symbolTable.StringsSectionIndex];
                                
                                List Relocations = relocTableSection.Relocations;
                                for (int k = 0; k < Relocations.Count; k++)
                                {
                                    ELFRelocationAddendTableSection.RelocationAddend relocation = (ELFRelocationAddendTableSection.RelocationAddend)Relocations[k];
                                    if (relocation.Type == ELFRelocationTableSection.RelocationType.R_386_NONE)
                                    {
                                        continue;
                                    }

                                    ELFSymbolTableSection.Symbol symbol = (ELFSymbolTableSection.Symbol)symbolTable[relocation.Symbol];
                                    FOS_System.String symbolName = symbolNamesTable[symbol.NameIdx];
                                    uint* resolvedRelLocation = (uint*)(SO.BaseAddress + (relocation.Offset - SO.TheFile.BaseAddress));

                                    //BasicConsole.WriteLine("Relocation:");
                                    ////BasicConsole.WriteLine("    > Symbol index : " + (FOS_System.String)relocation.Symbol);
                                    //BasicConsole.WriteLine("    > Type : " + (FOS_System.String)(uint)relocation.Type);
                                    //BasicConsole.WriteLine("    > Offset : " + (FOS_System.String)(uint)relocation.Offset);
                                    //BasicConsole.WriteLine(((FOS_System.String)"    > Resolved location address: ") + (uint)resolvedRelLocation);
                                    ////BasicConsole.WriteLine(((FOS_System.String)"    > Resolved location start value: ") + *resolvedRelLocation);
                                    //BasicConsole.Write("    > Symbol name : ");
                                    //BasicConsole.WriteLine(symbolName);
                                    
                                    uint newValue = 0;
                                    switch (relocation.Type)
                                    {
                                        //TODO: Support more relocation types
                                        default:
                                            Console.Default.WarningColour();
                                            Console.Default.Write("WARNING: Unrecognised relocation type! (");
                                            Console.Default.Write_AsDecimal((uint)relocation.Type);
                                            Console.Default.WriteLine(")");
                                            Console.Default.DefaultColour();

                                            BasicConsole.Write("WARNING: Unrecognised relocation type! (");
                                            BasicConsole.Write((uint)relocation.Type);
                                            BasicConsole.WriteLine(")");
                                            break;
                                    }

                                    *resolvedRelLocation = newValue;

                                    //BasicConsole.WriteLine("    > New value: " + (FOS_System.String)(newValue));
                                    //BasicConsole.WriteLine("    > Resolved location end value: " + (FOS_System.String)(*resolvedRelLocation));

                                }
                            }
                        }
                    }

                    Console.Default.WriteLine("Executable Relocations");
                    BasicConsole.WriteLine("Executable Relocations");

                    //BasicConsole.WriteLine("Executable base address : " + (FOS_System.String)BaseAddress);
                    //BasicConsole.WriteLine("Executable file base address : " + (FOS_System.String)theFile.BaseAddress);
                        
                    // Perform dynamic linking of executable
                    List ExeSections = theFile.Sections;
                    for (int j = 0; j < ExeSections.Count; j++)
                    {
                        ELFSection ExeSection = (ELFSection)ExeSections[j];
                        if (ExeSection is ELFRelocationTableSection)
                        {
                            //BasicConsole.WriteLine(" - Normal Relocations");

                            ELFRelocationTableSection relocTableSection = (ELFRelocationTableSection)ExeSection;
                            ELFSymbolTableSection symbolTable = (ELFSymbolTableSection)theFile.Sections[relocTableSection.SymbolTableSectionIndex];
                            ELFStringTableSection symbolNamesTable = (ELFStringTableSection)theFile.Sections[symbolTable.StringsSectionIndex];

                            List Relocations = relocTableSection.Relocations;
                            for (int k = 0; k < Relocations.Count; k++)
                            {
                                ELFRelocationTableSection.Relocation relocation = (ELFRelocationTableSection.Relocation)Relocations[k];
                                if (relocation.Type == ELFRelocationTableSection.RelocationType.R_386_NONE)
                                {
                                    continue;
                                }

                                uint* resolvedRelLocation = (uint*)(BaseAddress + (relocation.Offset - theFile.BaseAddress));
                                ELFSymbolTableSection.Symbol symbol = (ELFSymbolTableSection.Symbol)symbolTable[relocation.Symbol];
                                FOS_System.String symbolName = symbolNamesTable[symbol.NameIdx];
                                
                                //BasicConsole.WriteLine("Relocation:");
                                ////BasicConsole.WriteLine("    > Symbol index : " + (FOS_System.String)relocation.Symbol);
                                //BasicConsole.WriteLine("    > Type : " + (FOS_System.String)(uint)relocation.Type);
                                //BasicConsole.WriteLine("    > Offset : " + (FOS_System.String)(uint)relocation.Offset);
                                //BasicConsole.WriteLine(((FOS_System.String)"    > Resolved location address: ") + (uint)resolvedRelLocation);
                                ////BasicConsole.WriteLine(((FOS_System.String)"    > Resolved location start value: ") + *resolvedRelLocation);
                                //BasicConsole.Write("    > Symbol name : ");
                                //BasicConsole.WriteLine(symbolName);
                                    
                                bool setFromNewValue = true;
                                uint newValue = 0;
                                switch (relocation.Type)
                                {
                                    //TODO: Support more relocation types
                                    case ELFRelocationTableSection.RelocationType.R_386_JMP_SLOT:
                                        newValue = GetSymbolAddress(symbol, symbolName);
                                        break;
                                    case ELFRelocationTableSection.RelocationType.R_386_COPY:
                                        // Created by the link-editor for dynamic executables to preserve a read-only text segment. 
                                        // Its offset member refers to a location in a writable segment. The symbol table index 
                                        // specifies a symbol that should exist both in the current object file and in a shared object. 
                                        // During execution, the runtime linker copies data associated with the shared object's symbol 
                                        // to the location specified by the offset.
                                        // See Copy Relocations:
                                        //      http://docs.oracle.com/cd/E19683-01/817-3677/6mj8mbtbs/index.html#chapter4-84604

                                        setFromNewValue = false;
                                        uint symbolAddress = 0;
                                        uint symbolSize = 0;

                                        if (GetSymbolAddressAndSize(symbol, symbolName, ref symbolAddress, ref symbolSize))
                                        {
                                            byte* symbolValuePtr = (byte*)symbolAddress;

                                            //BasicConsole.Write("    > Symbol size : ");
                                            //BasicConsole.WriteLine(symbolSize);

                                            for (int i = 0; i < symbolSize; i++)
                                            {
                                                resolvedRelLocation[i] = symbolValuePtr[i];
                                            }
                                        }
                                        else
                                        {
                                            BasicConsole.WriteLine("Failed to get symbol address and size for R_386_COPY relocation!");
                                        }
                                        break;
                                    default:
                                        Console.Default.WarningColour();
                                        Console.Default.Write("WARNING: Unrecognised relocation type! (");
                                        Console.Default.Write_AsDecimal((uint)relocation.Type);
                                        Console.Default.WriteLine(")");
                                        Console.Default.DefaultColour();

                                        BasicConsole.Write("WARNING: Unrecognised relocation type! (");
                                        BasicConsole.Write((uint)relocation.Type);
                                        BasicConsole.WriteLine(")");
                                        break;
                                }
                                if (setFromNewValue)
                                {
                                    *resolvedRelLocation = newValue;
                                    //BasicConsole.WriteLine("    > New value: " + (FOS_System.String)(newValue));
                                    //BasicConsole.WriteLine("    > Resolved location end value: " + (FOS_System.String)(*resolvedRelLocation));
                                }
                            }
                        }
                        else if (ExeSection is ELFRelocationAddendTableSection)
                        {
                            //BasicConsole.WriteLine(" - Addend Relocations");

                            ELFRelocationAddendTableSection relocTableSection = (ELFRelocationAddendTableSection)ExeSection;
                            ELFSymbolTableSection symbolTable = (ELFSymbolTableSection)theFile.Sections[relocTableSection.SymbolTableSectionIndex];
                            ELFStringTableSection symbolNamesTable = (ELFStringTableSection)theFile.Sections[symbolTable.StringsSectionIndex];
                            
                            List Relocations = relocTableSection.Relocations;
                            for (int k = 0; k < Relocations.Count; k++)
                            {
                                ELFRelocationAddendTableSection.RelocationAddend relocation = (ELFRelocationAddendTableSection.RelocationAddend)Relocations[k];
                                if (relocation.Type == ELFRelocationTableSection.RelocationType.R_386_NONE)
                                {
                                    continue;
                                }

                                uint* resolvedRelLocation = (uint*)(BaseAddress + (relocation.Offset - theFile.BaseAddress));
                                ELFSymbolTableSection.Symbol symbol = (ELFSymbolTableSection.Symbol)symbolTable[relocation.Symbol];
                                FOS_System.String symbolName = symbolNamesTable[symbol.NameIdx];
                                
                                //BasicConsole.WriteLine("Relocation:");
                                ////BasicConsole.WriteLine("    > Symbol index : " + (FOS_System.String)relocation.Symbol);
                                //BasicConsole.WriteLine("    > Type : " + (FOS_System.String)(uint)relocation.Type);
                                //BasicConsole.WriteLine("    > Offset : " + (FOS_System.String)(uint)relocation.Offset);
                                //BasicConsole.WriteLine(((FOS_System.String)"    > Resolved location address: ") + (uint)resolvedRelLocation);
                                ////BasicConsole.WriteLine(((FOS_System.String)"    > Resolved location start value: ") + *resolvedRelLocation);
                                //BasicConsole.Write("    > Symbol name : ");
                                //BasicConsole.WriteLine(symbolName);
                                    
                                uint newValue = 0;
                                switch (relocation.Type)
                                {
                                    //TODO: Support more relocation types
                                    default:
                                        Console.Default.WarningColour();
                                        Console.Default.Write("WARNING: Unrecognised relocation type! (");
                                        Console.Default.Write_AsDecimal((uint)relocation.Type);
                                        Console.Default.WriteLine(")");
                                        Console.Default.DefaultColour();

                                        BasicConsole.Write("WARNING: Unrecognised relocation type! (");
                                        BasicConsole.Write((uint)relocation.Type);
                                        BasicConsole.WriteLine(")");
                                        break;
                                }
                                *resolvedRelLocation = newValue;
                                //BasicConsole.WriteLine("    > New value: " + (FOS_System.String)(newValue));
                                //BasicConsole.WriteLine("    > Resolved location end value: " + (FOS_System.String)(*resolvedRelLocation));
                            }
                        }
                    }

                    // TODO: Call Init functions of libraries
                }

                // Unmap processes' memory from current processes' memory
                for (int i = 0; i < SharedObjectDependencies.Count; i++)
                {
                    ELFSharedObject SO = (ELFSharedObject)SharedObjectDependencies[i];
                    uint FileBaseAddress = SO.TheFile.BaseAddress;
                    uint MemBaseAddress = SO.BaseAddress;

                    List SOSegments = SO.TheFile.Segments;
                    for (int j = 0; j < SOSegments.Count; j++)
                    {
                        ELFSegment SOSegment = (ELFSegment)SOSegments[j];
                        ProcessManager.CurrentProcess.TheMemoryLayout.RemovePage(
                            (MemBaseAddress + ((uint)SOSegment.Header.VAddr - FileBaseAddress)) & 0xFFFFF000);
                    }
                }
                {
                    uint FileBaseAddress = theFile.BaseAddress;
                    uint MemBaseAddress = BaseAddress;

                    List ExeSegments = theFile.Segments;
                    for (int j = 0; j < ExeSegments.Count; j++)
                    {
                        ELFSegment ExeSegment = (ELFSegment)ExeSegments[j];
                        ProcessManager.CurrentProcess.TheMemoryLayout.RemovePage(
                            (MemBaseAddress + ((uint)ExeSegment.Header.VAddr - FileBaseAddress)) & 0xFFFFF000);
                    }
                }

                #endregion

                ProcessManager.CurrentProcess.TheMemoryLayout.RemovePage(threadStackVirtAddr);

            }
            finally
            {
                if (!OK)
                {
                    theProcess = null;
                }
            }
        }
Beispiel #24
0
 private static bool Semaphore_VerifyOwner(int id, Process aProcess)
 {
     if (id > -1 && id < Semaphores.Count && Semaphores[id] != null)
     {
         Semaphore theSemaphore = ((Semaphore)Semaphores[id]);
         return theSemaphore.OwnerProcesses.IndexOf(aProcess.Id) > -1;
     }
     return false;
 }
Beispiel #25
0
        /// <summary>
        /// Attempts to read from the specified pipe.
        /// </summary>
        /// <remarks>
        /// Note that this function is non-blocking. It will, however, block a system caller thread by simply not returning it from
        /// the deferred system call.
        /// </remarks>
        /// <param name="PipeId">The Id of the pipe to read.</param>
        /// <param name="Blocking">Whether the read should be blocking or non-blocking.</param>
        /// <param name="CallerProcess">The process which made the call.</param>
        /// <param name="CallerThread">The thread which made the call.</param>
        /// <returns>See descriptions on <see cref="PipeManager.RWResults"/> values.</returns>
        public static RWResults ReadPipe(int PipeId, bool Blocking, Process CallerProcess, Thread CallerThread)
        {
#if PIPES_TRACE
            BasicConsole.WriteLine("ReadPipe: Validating inputs");
#endif
            // Validate inputs
            //  - Check pipe exists
            Pipe pipe = GetPipe(PipeId);
            if (pipe == null)
            {
                return RWResults.Error;
            }

#if PIPES_TRACE
            BasicConsole.WriteLine("ReadPipe: Checking caller allowed to write");
#endif
            // Check the caller is allowed to access the pipe
            if (!AllowedToReadPipe(pipe, CallerProcess.Id))
            {
                return RWResults.Error;
            }

#if PIPES_TRACE
            BasicConsole.WriteLine("ReadPipe: Getting out process");
#endif
            // Get outpoint process
            Process OutProcess = ProcessManager.GetProcessById(pipe.Outpoint.ProcessId);
            if (OutProcess == null)
            {
                return RWResults.Error;
            }

#if PIPES_TRACE
            BasicConsole.WriteLine("ReadPipe: Getting in process");
#endif
            // Get inpoint process
            Process InProcess = ProcessManager.GetProcessById(pipe.Inpoint.ProcessId);
            if (InProcess == null)
            {
                return RWResults.Error;
            }
            
#if PIPES_TRACE
            BasicConsole.WriteLine("ReadPipe: Adding caller to read queue");
#endif
            // Add caller thread to the read queue
            pipe.QueueToRead(CallerThread.Id);

            ProcessManager.EnableKernelAccessToProcessMemory(CallerProcess);
            // Set up initial failure return value
            CallerThread.Return1 = (uint)SystemCallResults.Fail;
            ProcessManager.DisableKernelAccessToProcessMemory(CallerProcess);

#if PIPES_TRACE
            BasicConsole.WriteLine("ReadPipe: Processing pipe queue");
#endif
            // Process the pipe queue
            ProcessPipeQueue(pipe, OutProcess, InProcess);
            
            bool Completed = !pipe.AreThreadsWaitingToRead();
            if (!Blocking)
            {
                if (!Completed)
                {
                    uint temp;
                    bool removed = pipe.RemoveLastToRead(out temp);

                    if (!removed || temp != CallerThread.Id)
                    {
                        BasicConsole.WriteLine("PipeManager: Error! Async read failed and then removing last from queue resulted in thread Id mismatch!");
                    }

                    ProcessManager.EnableKernelAccessToProcessMemory(CallerProcess);
                    CallerThread.Return1 = (uint)SystemCallResults.Fail;
                    ProcessManager.DisableKernelAccessToProcessMemory(CallerProcess);
                    CallerThread._Wake();
                }
            }
            return Completed ? RWResults.Complete : RWResults.Queued;
        }