diff --git a/kernel/include/modules/module.h b/kernel/include/modules/module.h index 49c94b63b..43b523ad9 100644 --- a/kernel/include/modules/module.h +++ b/kernel/include/modules/module.h @@ -33,6 +33,8 @@ typedef struct _MString MString_t; #define MODULE_FILESYSTEM 0x01010101 #define MODULE_BUS 0x02020202 +#define MODULE_INITIAL_STACK 0x1000 +#define MODULE_MAX_STACK (4 << 20) typedef enum _SystemModuleType { FileResource = 0, @@ -47,6 +49,7 @@ typedef struct _SystemModule { size_t Length; // Used by Module/Service type + clock_t StartedAt; MString_t* WorkingDirectory; MString_t* BaseDirectory; UUId_t PrimaryThreadId; diff --git a/kernel/include/modules/process.h b/kernel/include/modules/process.h deleted file mode 100644 index 6a75efa8e..000000000 --- a/kernel/include/modules/process.h +++ /dev/null @@ -1,80 +0,0 @@ -/* MollenOS - * - * Copyright 2018, Philip Meulengracht - * - * This program is free software : you can redistribute it and / or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation ? , either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program.If not, see . - * - * - * Alias & Process Management - * - The implementation of phoenix is responsible for managing alias's, handle - * file events and creating/destroying processes. - */ - -#ifndef __VALI_PROCESS_H__ -#define __VALI_PROCESS_H__ - -#include -#include -#include -#include - -typedef struct _SystemMemorySpace SystemMemorySpace_t; -typedef struct _MCorePeFile MCorePeFile_t; -typedef struct _MString MString_t; - -#define PROCESS_INITIAL_STACK 0x1000 -#define PROCESS_MAX_STACK (4 << 20) - -// Types of processes that can be created. -typedef enum _SystemProcessType { - ProcessNormal, - ProcessService -} SystemProcessType_t; - -// System process structure -// Data container that encompass a range of threads and shared resources -typedef struct _SystemProcess { - UUId_t MainThreadId; - clock_t StartedAt; - uintptr_t SignalHandler; // Move to memory space/store in thread -} SystemProcess_t; - -/* CreateProcess - * Creates a new handle, allocates a new handle and initializes a thread that performs - * the rest of setup required. */ -KERNELAPI OsStatus_t KERNELABI -CreateProcess( - _In_ MString_t* Path, - _In_ ProcessStartupInformation_t* StartupInformation, - _In_ SystemProcessType_t Type, - _Out_ UUId_t* Handle); - -/* DestroyProcess - * Callback invoked by the handle system when references on a process reaches zero */ -KERNELAPI OsStatus_t KERNELABI -DestroyProcess( - _In_ void* Resource); - -/* GetProcess - * This function retrieves the process structure by it's handle. */ -KERNELAPI SystemProcess_t* KERNELABI -GetProcess( - _In_ UUId_t Handle); - -/* GetCurrentProcess - * Retrieves the currently running process, identified by its thread. If none NULL is returned. */ -KERNELAPI SystemProcess_t* KERNELABI -GetCurrentProcess(void); - -#endif //!__VALI_PROCESS_H__ diff --git a/kernel/memoryspace.c b/kernel/memoryspace.c index 4d4b97dd3..ff8483037 100644 --- a/kernel/memoryspace.c +++ b/kernel/memoryspace.c @@ -22,7 +22,6 @@ */ #define __MODULE "MSPC" -#include #include #include #include @@ -105,6 +104,13 @@ CreateSystemMemorySpace( } } } + + // If we are root, create the memory bitmaps + if (MemorySpace->ParentHandle == UUID_INVALID) { + CreateBlockmap(0, GetMachine()->MemoryMap.UserHeap.Start, + GetMachine()->MemoryMap.UserHeap.Start + GetMachine()->MemoryMap.UserHeap.Length, + GetMachine()->MemoryGranularity, &MemorySpace->HeapSpace); + } CloneVirtualSpace(MemorySpace->Parent, MemorySpace, (Flags & MEMORY_SPACE_INHERIT) ? 1 : 0); *Handle = CreateHandle(HandleTypeMemorySpace, 0, MemorySpace); } diff --git a/kernel/modules/manager.c b/kernel/modules/manager.c index 75b68abd4..97416bb35 100644 --- a/kernel/modules/manager.c +++ b/kernel/modules/manager.c @@ -65,14 +65,15 @@ RegisterModule( memset(Module, 0, sizeof(SystemModule_t)); Module->ListHeader.Key.Value.Integer = (int)Type; + Module->Data = Data; Module->Path = MStringCreate("rd:/", StrUTF8); MStringAppendString(Module->Path, Path); - Module->Data = Data; - Module->VendorId = VendorId; - Module->DeviceId = DeviceId; - Module->DeviceClass = DeviceClass; - Module->DeviceSubclass = DeviceSubclass; + Module->VendorId = VendorId; + Module->DeviceId = DeviceId; + Module->DeviceClass = DeviceClass; + Module->DeviceSubclass = DeviceSubclass; + Module->PrimaryThreadId = UUID_INVALID; return CollectionAppend(&Modules, &Module->ListHeader); } @@ -213,7 +214,7 @@ GetCurrentModule(void) UUId_t ThreadId = ThreadingGetCurrentThreadId(); foreach(Node, &Modules) { SystemModule_t* Module = (SystemModule_t*)Node; - if (Module->PrimaryThreadId == ThreadId) { + if (Module->PrimaryThreadId == ThreadId /* || IsChildOf(Module->PrimaryThreadId)*/) { return Module; } } diff --git a/kernel/modules/module.c b/kernel/modules/module.c index 825f1d038..3e0efc8e1 100644 --- a/kernel/modules/module.c +++ b/kernel/modules/module.c @@ -33,62 +33,49 @@ #include #include -typedef struct _SystemProcessPackage { - UUId_t ProcessHandle; - uint8_t* FileBuffer; - size_t FileBufferLength; -} SystemProcessPackage_t; +typedef struct _SystemModulePackage { + SystemModule_t* Module; + const void* FileBuffer; + size_t FileBufferLength; + int FileBufferDynamic; +} SystemModulePackage_t; -/* ProcessThreadEntry - * This is the standard ash-boot function - * which simply sets up the ash and jumps to userland */ +/* ModuleThreadEntry + * Bootstraps the module, by relocating the image correctly into the module's address + * space and handles operatings that must be done on the same thread. */ void -ProcessThreadEntry( - _In_ void* Context) +ModuleThreadEntry( + _In_ void* Context) { - SystemProcessPackage_t* Package = (SystemProcessPackage_t*)Context; - SystemProcess_t* Process = (SystemProcess_t*)LookupHandle(Package->ProcessHandle); - UUId_t CurrentCpu = CpuGetCurrentId(); - MCoreThread_t* Thread = ThreadingGetCurrentThread(CurrentCpu); - uintptr_t BaseAddress; + SystemModulePackage_t* Package = (SystemModulePackage_t*)Context; + UUId_t CurrentCpu = CpuGetCurrentId(); + MCoreThread_t* Thread = ThreadingGetCurrentThread(CurrentCpu); + OsStatus_t Status; assert(Package != NULL); - assert(Process != NULL); - assert(Thread != NULL); - - // Argument when calling a new process is just NULL - Thread->ParentThreadId = UUID_INVALID; - Thread->ProcessHandle = Package->ProcessHandle; - - // Update currently running thread, by nulling parent we mark - // it as a standalone thread, which make sure it's not a part of a killable chain - Process->MainThreadId = Thread->Id; - Process->MemorySpace = GetCurrentSystemMemorySpace(); - TimersGetSystemTick(&Process->StartedAt); + TimersGetSystemTick(&Package->Module->StartedAt); // Setup base address for code data TRACE("Loading PE-image into memory (buffer 0x%x, size %u)", Package->FileBuffer, Package->FileBufferLength); - BaseAddress = GetMachine()->MemoryMap.UserCode.Start; - Process->Executable = PeLoadImage(NULL, Process->Name, Package->FileBuffer, - Package->FileBufferLength, &BaseAddress, Package->LoadedFromInitRD); - Process->NextLoadingAddress = BaseAddress; - - // Update entry functions - assert(Process->Executable != NULL); - Thread->Function = (ThreadEntry_t)Process->Executable->EntryAddress; - Thread->Arguments = NULL; - - if (!Package->LoadedFromInitRD) { + Status = PeLoadImage(NULL, Process->Name, Package->Module->Path, (uint8_t*)Package->FileBuffer, + Package->FileBufferLength, &Package->Module->Executable); + if (Status == OsSuccess) { + Thread->Function = (ThreadEntry_t)Package->Module->Executable->EntryAddress; + Thread->Arguments = NULL; + } + else { + ERROR("Failed to bootstrap pe image: %u", Status); + } + + if (Package->FileBufferDynamic) { kfree(Package->FileBuffer); } kfree(Package); - - // Initialize the memory bitmaps - CreateBlockmap(0, GetMachine()->MemoryMap.UserHeap.Start, - GetMachine()->MemoryMap.UserHeap.Start + GetMachine()->MemoryMap.UserHeap.Length, - GetMachine()->MemoryGranularity, &Process->Heap); - ThreadingSwitchLevel(); + + if (Status == OsSuccess) { + ThreadingSwitchLevel(); + } } /* SpawnModule @@ -99,29 +86,51 @@ SpawnModule( _In_ const void* Data, _In_ size_t Length) { - SystemProcessPackage_t* Package; - int Index; - UUId_t ThreadId; + SystemModulePackage_t* Package; + int Index; + OsStatus_t Status; + MString_t* Name; assert(Module != NULL); assert(Module->Executable == NULL); + Package = (SystemModulePackage_t*)kmalloc(sizeof(SystemModulePackage_t)); + Package->FileBuffer = Data; + Package->FileBufferLength = Length; + Package->Module = Module; + Package->FileBufferDynamic = 1; + // If no data is passed the data stored initially in module structure // must be present if (Data == NULL || Length == 0) { assert(Module->Data != NULL && Module->Length != 0); + Package->FileBuffer = Module->Data; + Package->FileBufferLength = Module->Length; + Package->FileBufferDynamic = 0; } + Status = PeValidateImageBuffer((uint8_t*)Package->FileBuffer, Package->FileBufferLength); + if (Status != OsSuccess) { + kfree(Package); + return Status; + } + + // Create initial resources + Module->Rpc = CreateSystemPipe(PIPE_MPMC | PIPE_STRUCTURED_BUFFER, PIPE_DEFAULT_ENTRYCOUNT); + // Split path, even if a / is not found // it won't fail, since -1 + 1 = 0, so we just copy the entire string - Index = MStringFindReverse(Process->Path, '/', 0); - Process->WorkingDirectory = MStringSubString(Process->Path, 0, Index); - Process->BaseDirectory = MStringSubString(Process->Path, 0, Index); - Process->Name = MStringSubString(Process->Path, Index + 1, -1); - Process->Pipes = CollectionCreate(KeyInteger); - Process->FileMappings = CollectionCreate(KeyInteger); - Process->Type = Type; - CreateThread(MStringRaw(Process->Name), ProcessThreadEntry, Package, THREADING_USERMODE, UUID_INVALID, &ThreadId); - ThreadingDetachThread(ThreadId); + Index = MStringFindReverse(Module->Path, '/', 0); + Module->WorkingDirectory = MStringSubString(Module->Path, 0, Index); + Module->BaseDirectory = MStringSubString(Module->Path, 0, Index); + Name = MStringSubString(Module->Path, Index + 1, -1); + Status = CreateThread(MStringRaw(Name), ModuleThreadEntry, Package, + THREADING_USERMODE, UUID_INVALID, &Module->PrimaryThreadId); + MStringDestroy(Name); + if (Status != OsSuccess) { + kfree(Package); + return Status; + } + ThreadingDetachThread(Module->PrimaryThreadId); return OsSuccess; } diff --git a/kernel/system_calls/driver_calls.c b/kernel/system_calls/driver_calls.c index 73190ab75..4459f2dea 100644 --- a/kernel/system_calls/driver_calls.c +++ b/kernel/system_calls/driver_calls.c @@ -21,11 +21,8 @@ #define __MODULE "SCIF" //#define __TRACE -#include -#include -#include +#include #include -#include #include #include #include @@ -129,8 +126,15 @@ ScAcpiQueryInterrupt( * or atleast dummy-implementation */ OsStatus_t ScIoSpaceRegister( - _In_ DeviceIo_t* IoSpace) + _In_ DeviceIo_t* IoSpace) { + SystemModule_t* Module = GetCurrentModule(); + if (IoSpace == NULL || Module == NULL) { + if (Module == NULL) { + return OsInvalidPermission; + } + return OsError; + } return RegisterSystemDeviceIo(IoSpace); } @@ -140,8 +144,15 @@ ScIoSpaceRegister( * two drivers using the same device */ OsStatus_t ScIoSpaceAcquire( - _In_ DeviceIo_t* IoSpace) + _In_ DeviceIo_t* IoSpace) { + SystemModule_t* Module = GetCurrentModule(); + if (IoSpace == NULL || Module == NULL) { + if (Module == NULL) { + return OsInvalidPermission; + } + return OsError; + } return AcquireSystemDeviceIo(IoSpace); } @@ -151,8 +162,15 @@ ScIoSpaceAcquire( * two drivers using the same device */ OsStatus_t ScIoSpaceRelease( - _In_ DeviceIo_t* IoSpace) + _In_ DeviceIo_t* IoSpace) { + SystemModule_t* Module = GetCurrentModule(); + if (IoSpace == NULL || Module == NULL) { + if (Module == NULL) { + return OsInvalidPermission; + } + return OsError; + } return ReleaseSystemDeviceIo(IoSpace); } @@ -162,8 +180,15 @@ ScIoSpaceRelease( * can only be removed if its not already acquired */ OsStatus_t ScIoSpaceDestroy( - _In_ DeviceIo_t* IoSpace) + _In_ DeviceIo_t* IoSpace) { + SystemModule_t* Module = GetCurrentModule(); + if (IoSpace == NULL || Module == NULL) { + if (Module == NULL) { + return OsInvalidPermission; + } + return OsError; + } return DestroySystemDeviceIo(IoSpace); } @@ -172,20 +197,9 @@ ScIoSpaceDestroy( * its id if it changes */ OsStatus_t ScRegisterAliasId( - _In_ UUId_t Alias) + _In_ UUId_t Alias) { - SystemProcess_t* Process = GetCurrentProcess(); - TRACE("ScRegisterAliasId(Server %s, Alias 0x%X)", MStringRaw(Process->Name), Alias); - - // Update the registered sys pipe that should recieve input events from cursor etc - if (SetProcessAlias(ThreadingGetCurrentThread(CpuGetCurrentId())->ProcessHandle, Alias) == OsSuccess) { - if (Alias == __WINDOWMANAGER_TARGET) { - GetMachine()->StdInput = GetProcessPipe(Process, PIPE_STDIN); - GetMachine()->WmInput = GetProcessPipe(Process, PIPE_WMEVENTS); - } - return OsSuccess; - } - return OsError; + return SetModuleAlias(Alias); } /* ScLoadDriver @@ -261,7 +275,8 @@ ScRegisterInterrupt( _In_ DeviceInterrupt_t* Interrupt, _In_ Flags_t Flags) { - if (Interrupt == NULL || + SystemModule_t* Module = GetCurrentModule(); + if (Interrupt == NULL || Module == NULL || (Flags & (INTERRUPT_KERNEL | INTERRUPT_SOFT))) { return UUID_INVALID; } @@ -275,14 +290,24 @@ OsStatus_t ScUnregisterInterrupt( _In_ UUId_t Source) { + SystemModule_t* Module = GetCurrentModule(); + if (Module == NULL) { + return OsInvalidPermission; + } return InterruptUnregister(Source); } +OsStatus_t ScRegisterEventTarget(UUId_t KeyInput, UUId_t WmInput) +{ + //GetMachine()->StdInput = GetProcessPipe(Process, PIPE_STDIN); + //GetMachine()->WmInput = GetProcessPipe(Process, PIPE_WMEVENTS); +} + /* ScKeyEvent * Handles key notification by redirecting them to the standard input in the system. */ OsStatus_t ScKeyEvent( - _In_ SystemKey_t* Key) + _In_ SystemKey_t* Key) { if (GetMachine()->StdInput != NULL) { return WriteSystemPipe(GetMachine()->StdInput, (const uint8_t*)Key, sizeof(SystemKey_t)); @@ -294,7 +319,7 @@ ScKeyEvent( * Handles input notification by redirecting them to the window manager input. */ OsStatus_t ScInputEvent( - _In_ SystemInput_t* Input) + _In_ SystemInput_t* Input) { if (GetMachine()->WmInput != NULL) { return WriteSystemPipe(GetMachine()->WmInput, (const uint8_t*)Input, sizeof(SystemInput_t)); @@ -308,9 +333,9 @@ ScInputEvent( * the owner of the timer. */ UUId_t ScTimersStart( - _In_ size_t Interval, - _In_ int Periodic, - _In_ const void* Data) + _In_ size_t Interval, + _In_ int Periodic, + _In_ const void* Data) { return TimersStart(Interval, Periodic, Data); } @@ -320,6 +345,6 @@ ScTimersStart( * process. Otherwise access fault. */ OsStatus_t ScTimersStop( - _In_ UUId_t TimerId) { + _In_ UUId_t TimerId) { return TimersStop(TimerId); } diff --git a/kernel/system_calls/ipc_calls.c b/kernel/system_calls/ipc_calls.c index 454aa27fb..9d349cef7 100644 --- a/kernel/system_calls/ipc_calls.c +++ b/kernel/system_calls/ipc_calls.c @@ -21,9 +21,6 @@ #define __MODULE "SCIF" //#define __TRACE -#include -#include -#include #include #include #include @@ -38,8 +35,8 @@ * communication to this port from other processes */ OsStatus_t ScPipeOpen( - _In_ int Port, - _In_ int Type) + _In_ int Port, + _In_ int Type) { SystemProcess_t* Process = GetCurrentProcess(); if (Process != NULL) { diff --git a/kernel/system_calls/memory_calls.c b/kernel/system_calls/memory_calls.c index 5868ab5a2..23a86b42f 100644 --- a/kernel/system_calls/memory_calls.c +++ b/kernel/system_calls/memory_calls.c @@ -25,7 +25,7 @@ #include #include -#include +#include #include #include #include @@ -41,15 +41,15 @@ ScMemoryAllocate( _Out_ uintptr_t* VirtualAddress, _Out_ uintptr_t* PhysicalAddress) { - uintptr_t AllocatedAddress; - SystemProcess_t* Process = GetCurrentProcess(); - if (Process == NULL || Size == 0) { + uintptr_t AllocatedAddress; + SystemMemorySpace_t* Space = GetCurrentSystemMemorySpace(); + if (Space->HeapSpace == NULL || Size == 0) { return OsError; } // Now do the allocation in the user-bitmap // since memory is managed in userspace for speed - AllocatedAddress = AllocateBlocksInBlockmap(Process->Heap, __MASK, Size); + AllocatedAddress = AllocateBlocksInBlockmap(Space->HeapSpace, __MASK, Size); if (AllocatedAddress == 0) { return OsError; } @@ -105,14 +105,14 @@ ScMemoryFree( _In_ uintptr_t Address, _In_ size_t Size) { - SystemProcess_t* Process = GetCurrentProcess(); - if (Process == NULL || Address == 0 || Size == 0) { + SystemMemorySpace_t* Space = GetCurrentSystemMemorySpace(); + if (Space->HeapSpace == NULL || Address == 0 || Size == 0) { return OsError; } // Now do the deallocation in the user-bitmap // since memory is managed in userspace for speed - if (ReleaseBlockmapRegion(Process->Heap, Address, Size) != OsSuccess) { + if (ReleaseBlockmapRegion(Space->HeapSpace, Address, Size) != OsSuccess) { ERROR("ScMemoryFree(Address 0x%x, Size 0x%x) was invalid", Address, Size); return OsError; } @@ -124,12 +124,12 @@ ScMemoryFree( * and returns allocation information or stats depending on query function */ OsStatus_t ScMemoryQuery( - _Out_ MemoryDescriptor_t *Descriptor) + _Out_ MemoryDescriptor_t* Descriptor) { Descriptor->AllocationGranularityBytes = GetMachine()->MemoryGranularity; - Descriptor->PageSizeBytes = GetSystemMemoryPageSize(); - Descriptor->PagesTotal = GetMachine()->PhysicalMemory.BlockCount; - Descriptor->PagesUsed = GetMachine()->PhysicalMemory.BlocksAllocated; + Descriptor->PageSizeBytes = GetSystemMemoryPageSize(); + Descriptor->PagesTotal = GetMachine()->PhysicalMemory.BlockCount; + Descriptor->PagesUsed = GetMachine()->PhysicalMemory.BlocksAllocated; return OsSuccess; } @@ -138,12 +138,11 @@ ScMemoryQuery( * made by MemoryAllocate */ OsStatus_t ScMemoryProtect( - _In_ void* MemoryPointer, - _In_ size_t Length, - _In_ Flags_t Flags, - _Out_ Flags_t* PreviousFlags) + _In_ void* MemoryPointer, + _In_ size_t Length, + _In_ Flags_t Flags, + _Out_ Flags_t* PreviousFlags) { - // Variables uintptr_t AddressStart = (uintptr_t)MemoryPointer; if (MemoryPointer == NULL || Length == 0) { return OsSuccess; @@ -164,7 +163,6 @@ ScCreateBuffer( _In_ size_t Size, _Out_ DmaBuffer_t* MemoryBuffer) { - // Variables if (MemoryBuffer == NULL || Size == 0) { return OsError; } @@ -179,7 +177,6 @@ ScAcquireBuffer( _In_ UUId_t Handle, _Out_ DmaBuffer_t* MemoryBuffer) { - // Variables if (MemoryBuffer == NULL || Handle == UUID_INVALID) { return OsError; } @@ -195,7 +192,6 @@ ScQueryBuffer( _Out_ uintptr_t* Dma, _Out_ size_t* Capacity) { - // Variables if (Capacity == NULL || Dma == NULL || Handle == UUID_INVALID) { return OsError; } @@ -207,7 +203,11 @@ ScCreateSystemMemorySpace( _In_ Flags_t Flags, _Out_ UUId_t* Handle) { - if (Handle == NULL /*|| !IsPrivilegedProcess() */) { + SystemModule_t* Module = GetCurrentModule(); + if (Handle == NULL || Module == NULL) { + if (Module == NULL) { + return OsInvalidPermission; + } return OsError; } return CreateSystemMemorySpace(Flags | MEMORY_SPACE_APPLICATION, Handle); @@ -218,8 +218,12 @@ ScGetThreadMemorySpaceHandle( _In_ UUId_t ThreadHandle, _Out_ UUId_t* Handle) { - MCoreThread_t* Thread; - if (Handle == NULL /*|| !IsPrivilegedProcess() */) { + MCoreThread_t* Thread; + SystemModule_t* Module = GetCurrentModule(); + if (Handle == NULL || Module == NULL) { + if (Module == NULL) { + return OsInvalidPermission; + } return OsError; } Thread = ThreadingGetThread(ThreadHandle); @@ -236,10 +240,14 @@ ScCreateSystemMemorySpaceMapping( _In_ struct MemoryMappingParameters* Parameters, _In_ DmaBuffer_t* AccessBuffer) { + SystemModule_t* Module = GetCurrentModule(); SystemMemorySpace_t* MemorySpace = (SystemMemorySpace_t*)LookupHandle(Handle); Flags_t RequiredFlags = MAPPING_USERSPACE | MAPPING_PROVIDED | MAPPING_FIXED; OsStatus_t Status; - if (Parameters == NULL || AccessBuffer == NULL /*|| !IsPrivilegedProcess() */) { + if (Parameters == NULL || AccessBuffer == NULL || Module == NULL) { + if (Module == NULL) { + return OsInvalidPermission; + } return OsError; } if (MemorySpace == NULL) { diff --git a/kernel/system_calls/table.c b/kernel/system_calls/table.c index 80991878f..20ec8d493 100644 --- a/kernel/system_calls/table.c +++ b/kernel/system_calls/table.c @@ -21,7 +21,6 @@ #define DefineSyscall(_Sys) ((uintptr_t)&_Sys) #include -#include #include #include #include @@ -127,6 +126,7 @@ OsStatus_t ScRegisterAliasId(UUId_t Alias); OsStatus_t ScLoadDriver(MCoreDevice_t* Device, size_t Length); UUId_t ScRegisterInterrupt(DeviceInterrupt_t* Interrupt, Flags_t Flags); OsStatus_t ScUnregisterInterrupt(UUId_t Source); +OsStatus_t ScRegisterEventTarget(UUId_t KeyInput, UUId_t WmInput); OsStatus_t ScKeyEvent(SystemKey_t* Key); OsStatus_t ScInputEvent(SystemInput_t* Input); UUId_t ScTimersStart(size_t Interval, int Periodic, const void* Data); @@ -257,7 +257,7 @@ uintptr_t GlbSyscallTable[111] = { * - Support */ DefineSyscall(ScRegisterAliasId), DefineSyscall(ScLoadDriver), - DefineSyscall(NoOperation), + DefineSyscall(ScRegisterEventTarget), DefineSyscall(NoOperation), DefineSyscall(NoOperation), DefineSyscall(NoOperation), diff --git a/librt/libds/pe/load.c b/librt/libds/pe/load.c index 92abb25a4..29523ae7e 100644 --- a/librt/libds/pe/load.c +++ b/librt/libds/pe/load.c @@ -31,11 +31,11 @@ * It also returns the last memory address of the relocations */ OsStatus_t PeHandleSections( + _In_ PeExecutable_t* Parent, _In_ PeExecutable_t* Image, _In_ uint8_t* Data, _In_ uintptr_t SectionAddress, - _In_ int SectionCount, - _Out_ uintptr_t* NextAvailableAddress) + _In_ int SectionCount) { PeSectionHeader_t* Section = (PeSectionHeader_t*)SectionAddress; uintptr_t CurrentAddress = Image->VirtualAddress; @@ -109,7 +109,9 @@ PeHandleSections( if (CurrentAddress % GetSystemMemoryPageSize()) { CurrentAddress += (GetSystemMemoryPageSize() - (CurrentAddress % GetSystemMemoryPageSize())); } - *NextAvailableAddress = CurrentAddress; + + if (Parent != NULL) Parent->NextLoadingAddress = CurrentAddress; + else Image->NextLoadingAddress = CurrentAddress; return OsSuccess; } @@ -244,15 +246,14 @@ PeResolveImportDescriptor( _In_ PeExecutable_t* Parent, _In_ PeExecutable_t* Image, _In_ PeImportDescriptor_t* ImportDescriptor, - _In_ MString_t* ImportDescriptorName, - _InOut_ uintptr_t* NextImageBase) + _In_ MString_t* ImportDescriptorName) { PeExecutable_t* ResolvedLibrary; PeExportedFunction_t* Exports; int NumberOfExports; // Resolve the library from the import chunk - ResolvedLibrary = PeResolveLibrary(Parent, Image, Name, NextImageBase); + ResolvedLibrary = PeResolveLibrary(Parent, Image, Name); if (ResolvedLibrary == NULL || ResolvedLibrary->ExportedFunctions == NULL) { dserror("(%s): Failed to resolve library %s", MStringRaw(Image->Name), MStringRaw(Name)); return OsError; @@ -344,8 +345,7 @@ OsStatus_t PeHandleImports( _In_ PeExecutable_t* Parent, _In_ PeExecutable_t* Image, - _In_ PeDataDirectory_t* ImportDirectory, - _InOut_ uintptr_t* NextImageBase) + _In_ PeDataDirectory_t* ImportDirectory) { PeImportDescriptor_t* ImportDescriptor; @@ -357,7 +357,7 @@ PeHandleImports( while (ImportDescriptor->ImportAddressTable != 0) { char* NamePtr = (char*)(Image->VirtualAddress + ImportDescriptor->ModuleName); MString_t* Name = MStringCreate(NamePtr, StrUTF8); - OsStatus_t Status = PeResolveImportDescriptor(Parent, Image, ImportDescriptor, Name, NextImageBase); + OsStatus_t Status = PeResolveImportDescriptor(Parent, Image, ImportDescriptor, Name); MStringDestroy(Name); if (Status != OsSuccess) { @@ -372,9 +372,14 @@ PeHandleImports( * Parses sections, data directories and performs neccessary translations and mappings. */ OsStatus_t PeParseAndMapImage( - _In_ PeExecutable_t* Image, - _In_ size_t SizeOfMetaData, - _InOut_ uintptr_t* BaseAddress) + _In_ PeExecutable_t* Parent, + _In_ PeExecutable_t* Image, + _In_ uint8_t* ImageBuffer, + _In_ uintptr_t ImageBase, + _In_ size_t SizeOfMetaData, + _In_ uintptr_t SectionBase, + _In_ size_t SectionCount, + _In_ PeDataDirectory_t* DirectoryPointer) { uintptr_t VirtualAddress = Image->VirtualAddress; MemoryMapHandle_t MapHandle; @@ -387,19 +392,19 @@ PeParseAndMapImage( dserror("Failed to map pe's metadata, out of memory?"); return OsError; } - memcpy((void*)VirtualAddress, Buffer, SizeOfMetaData); + memcpy((void*)VirtualAddress, ImageBuffer, SizeOfMetaData); ReleaseImageMapping(MapHandle); // Now we want to handle all the directories // and sections in the image, start out by handling // the sections, then parse all directories dstrace("Handling sections, relocations and exports"); - Status = PeHandleSections(Image, Buffer, SectionAddress, BaseHeader->NumSections, 1, BaseAddress); + Status = PeHandleSections(Parent, Image, ImageBuffer, SectionBase, SectionCount); if (Status != OsSuccess) { return OsError; } - PeHandleRelocations(Image, ImageBase, &DirectoryPtr[PE_SECTION_BASE_RELOCATION]); - PeHandleExports(Image, &DirectoryPtr[PE_SECTION_EXPORT]); + PeHandleRelocations(Image, ImageBase, &DirectoryPointer[PE_SECTION_BASE_RELOCATION]); + PeHandleExports(Image, &DirectoryPointer[PE_SECTION_EXPORT]); // Before loading imports, add us to parent list of libraries // so we might be reused, instead of reloaded @@ -407,7 +412,7 @@ PeParseAndMapImage( DataKey_t Key = { 0 }; CollectionAppend(Parent->Libraries, CollectionCreateNode(Key, Image)); } - Status = PeHandleImports(Parent, Image, &DirectoryPtr[PE_SECTION_IMPORT], BaseAddress); + Status = PeHandleImports(Parent, Image, &DirectoryPointer[PE_SECTION_IMPORT]); return Status; } @@ -422,7 +427,6 @@ PeLoadImage( _In_ MString_t* FullPath, _In_ uint8_t* Buffer, _In_ size_t Length, - _InOut_ uintptr_t* BaseAddress, _Out_ PeExecutable_t** ImageOut) { MzHeader_t* DosHeader; @@ -440,7 +444,7 @@ PeLoadImage( dstrace("PeLoadImage(Path %s, Parent %s, Address 0x%x)", MStringRaw(Name), (Parent == NULL) ? "None" : MStringRaw(Parent->Name), - *BaseAddress); + GetBaseAddress()); if (PeValidateImageBuffer(Buffer, Length) != OsSuccess) { return OsError; @@ -497,7 +501,7 @@ PeLoadImage( Image->Name = MStringCreate((void*)MStringRaw(Name), StrUFT8); Image->FullPath = MStringCreate((void*)MStringRaw(FullPath), StrUFT8); Image->Architecture = OptHeader->Architecture; - Image->VirtualAddress = *BaseAddress; + Image->VirtualAddress = (Parent == NULL) ? GetBaseAddress() : Parent->NextLoadingAddress; Image->Libraries = CollectionCreate(KeyInteger); Image->References = 1; @@ -516,7 +520,8 @@ PeLoadImage( return OsError; } - Status = PeParseAndMapImage(Image, SizeOfMetaData, BaseAddress); + Status = PeParseAndMapImage(Parent, Image, Buffer, ImageBase, SizeOfMetaData, SectionAddress, + BaseHeader->NumSections, DirectoryPtr); if (Status != OsSuccess) { PeUnloadLibrary(Parent, Image); return OsError; diff --git a/librt/libds/pe/pe.h b/librt/libds/pe/pe.h index 42b802f73..b9ae122f6 100644 --- a/librt/libds/pe/pe.h +++ b/librt/libds/pe/pe.h @@ -71,6 +71,7 @@ typedef struct _PeExecutable { /******************************************************************************* * Support Methods *******************************************************************************/ +__EXTERN uintptr_t GetBaseAddress(void); __EXTERN OsStatus_t LoadFile(MString_t*, MString_t**, void**, size_t*); __EXTERN OsStatus_t CreateImageSpace(MemorySpaceHandle_t*); __EXTERN OsStatus_t AcquireImageMapping(MemorySpaceHandle_t, uintptr_t*, size_t, Flags_t, MemoryMapHandle_t*); @@ -99,7 +100,6 @@ PeLoadImage( _In_ MString_t* FullPath, _In_ uint8_t* Buffer, _In_ size_t Length, - _InOut_ uintptr_t* BaseAddress, _Out_ PeExecutable_t** ImageOut); /* PeUnloadImage @@ -123,8 +123,7 @@ __EXTERN PeExecutable_t* PeResolveLibrary( _In_ PeExecutable_t* Parent, _In_ PeExecutable_t* Image, - _In_ MString_t* LibraryName, - _InOut_ uintptr_t* LoadAddress); + _In_ MString_t* LibraryName); /* PeResolveFunction * Resolves a function by name in the given pe image, the return diff --git a/librt/libds/pe/utilities.c b/librt/libds/pe/utilities.c index fc4b44e39..7d0af1b1e 100644 --- a/librt/libds/pe/utilities.c +++ b/librt/libds/pe/utilities.c @@ -33,14 +33,13 @@ PeExecutable_t* PeResolveLibrary( _In_ PeExecutable_t* Parent, _In_ PeExecutable_t* Image, - _In_ MString_t* LibraryName, - _InOut_ uintptr_t* LoadAddress) + _In_ MString_t* LibraryName) { PeExecutable_t* ExportParent = Parent; PeExecutable_t* Exports = NULL; OsStatus_t Status; - dstrace("PeResolveLibrary(Name %s, Address 0x%x)", MStringRaw(LibraryName), *LoadAddress); + dstrace("PeResolveLibrary(Name %s)", MStringRaw(LibraryName)); if (ExportParent == NULL) { ExportParent = Image; } @@ -65,7 +64,7 @@ PeResolveLibrary( Status = LoadFile(LibraryName, &FullPath, (void**)&Buffer, &Size); if (Status == OsSuccess) { - Status = PeLoadImage(ExportParent, LibraryName, FullPath, Buffer, Size, LoadAddress, &Exports); + Status = PeLoadImage(ExportParent, LibraryName, FullPath, Buffer, Size, &Exports); } } diff --git a/librt/libds/support/ds.c b/librt/libds/support/ds.c index 739a3c3fa..94f775d48 100644 --- a/librt/libds/support/ds.c +++ b/librt/libds/support/ds.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -167,6 +168,15 @@ int dssortkey(KeyType_t type, DataKey_t key1, DataKey_t key2) /******************************************************************************* * Support Methods (PE) *******************************************************************************/ +uintptr_t GetBaseAddress(void) +{ +#ifdef LIBC_KERNEL + return GetMachine()->MemoryMap.UserCode.Start; +#else + return 0; +#endif +} + OsStatus_t LoadFile(MString_t* Path, MString_t** FullPath, void** BufferOut, size_t* LengthOut) { OsStatus_t Status;