1 using System;
  2 using System.Collections;
  3 using System.IO;
  4 using cmsx.machine;
  5 using cmsx.object;
  6 
  7 namespace cmsx.kernel
  8 {
  9     public Section MakePoolSection(const List<string>& argvconst List<string>& environmentulong& envDataAddress)
 10     {
 11         Section poolSection;
 12         long n = argv.Count() + 1;
 13         for (long i = 0; i < n; ++i;)
 14         {
 15             poolSection.EmitULong(0u);
 16         }
 17         long envBeginPos = poolSection.pos;
 18         envDataAddress = poolSegmentBaseAddress + poolSection.Address();
 19         long m = environment.Count() + 1;
 20         for (long i = 0; i < m; ++i;)
 21         {
 22             poolSection.EmitULong(0u);
 23         }
 24         poolSection.Align(8u);
 25         List<ulong> argAddresses;
 26         for (const string& arg : argv)
 27         {
 28             argAddresses.Add(poolSegmentBaseAddress + poolSection.Address());
 29             poolSection.EmitString(arg);
 30         }
 31         poolSection.Align(8u);
 32         List<ulong> envAddresses;
 33         for (const string& env : environment)
 34         {
 35             envAddresses.Add(poolSegmentBaseAddress + poolSection.Address());
 36             poolSection.EmitString(env);
 37         }
 38         poolSection.pos = 0;
 39         for (ulong argAddr : argAddresses)
 40         {
 41             poolSection.EmitULong(argAddr);
 42         }
 43         poolSection.pos = envBeginPos;
 44         for (ulong envAddr : envAddresses)
 45         {
 46             poolSection.EmitULong(envAddr);
 47         }
 48         return poolSection;
 49     }
 50 
 51     public int Load(const string& programFileNameconst List<string>& programArgumentsint sid)
 52     {
 53         UniquePtr<BinaryFile> binaryFile = ReadBinaryFile(programFileName);
 54         if (binaryFile.Get() is ExecutableFile*)
 55         {
 56             Machine& machine = GetMachine();
 57             ProcessTable& processTable = GetProcessTable();
 58             ExecutableFile* executable = cast<ExecutableFile*>(binaryFile.Get());
 59             executable->AddSymbolsToAddressMap();
 60             Section* codeSection = executable->GetCodeSection();
 61             Section* dataSection = executable->GetDataSection();
 62             Section* symbolSection = executable->GetSymbolSection();
 63             string name = Path.GetFileName(programFileName);
 64             List<string> argv;
 65             argv.Add(name);
 66             for (const string& arg : programArguments)
 67             {
 68                 argv.Add(arg);
 69             }
 70             ulong envDataAddress = 0u;
 71             Section poolSection = MakePoolSection(argvList<string>()envDataAddress);
 72             long poolDataLength = Max(cast<long>(executable->InitialPoolSize())poolSection.data.Count());
 73             long poolSize = Align(poolDataLengthcast<long>(pageSize));
 74             Symbol* mainFunctionSymbol = executable->GetSymbolTable().GetSymbol("Main");
 75             Process* process = CreateSingleProcess(machineprocessTablenamemainFunctionSymbol->startcodeSection->BaseAddress()codeSection->DataLength()dataSection->DataLength()cast<ulong>(poolSize)
 76                 cast<ulong>(executable->MinStackSize())cast<ulong>(executable->MaxStackSize())cast<ulong>(executable->StackSizeIncrement())sid);
 77             if (codeSection->DataLength() > 0u)
 78             {
 79                 WriteProcessMemory(machineprocesscodeSection->BaseAddress()codeSection->data.Begin().Ptr()cast<ulong>(codeSection->data.Count())Protection.execute);
 80             }
 81             if (dataSection->DataLength() > 0u)
 82             {
 83                 WriteProcessMemory(machineprocessdataSection->BaseAddress()dataSection->data.Begin().Ptr()cast<ulong>(dataSection->data.Count())Protection.write);
 84             }
 85             if (!poolSection.data.IsEmpty())
 86             {
 87                 WriteProcessMemory(machineprocesspoolSegmentBaseAddresspoolSection.data.Begin().Ptr()cast<ulong>(poolSection.data.Count())Protection.write);
 88                 int ax = cast<int>(argv.Count());
 89                 ulong bx = poolSegmentBaseAddress;
 90                 WriteProcessMemory(machineprocessprocess->regAXAddresscast<ulong>(ax)8uProtection.write);
 91                 WriteProcessMemory(machineprocessprocess->regBXAddressbx8uProtection.write);
 92                 WriteProcessMemory(machineprocessprocess->regCXAddress0u8uProtection.write);
 93             }
 94             ulong poolStart = poolSegmentBaseAddress + cast<ulong>(poolSize);
 95             ulong poolEnd = poolSegmentBaseAddress + cast<ulong>(poolSize);
 96             process->poolStart = poolStart;
 97             process->poolEnd = poolEnd;
 98             Symbol* functionTableSymbol = executable->GetSymbolTable().GetSymbol("@function_table");
 99             process->functionTableAddress = functionTableSymbol->start;
100             process->functionTableLength = functionTableSymbol->length;
101             executable = cast<ExecutableFile*>(binaryFile.Release());
102             Kernel& kernel = Kernel.Instance();
103             kernel.SetExecutable(executable);
104             Session* session = kernel.CurrentSession();
105             session->fgpid = process->pid;
106             return process->pid;
107         }
108         else
109         {
110             Panic("file '" + programFileName + "' is not a CMSX executable");
111         }
112         return -1;
113     }
114 }