The Pedigree Project
0.1
|
#include <PosixSubsystem.h>
Classes | |
struct | AlternateSignalStack |
class | PosixSyncObject |
class | PosixThread |
struct | PosixThreadKey |
struct | SignalHandler |
Public Types | |
enum | Abi { PosixAbi = 0, LinuxAbi = 1 } |
Public Types inherited from Subsystem | |
enum | SubsystemType { Posix = 0, Native = 1, None = 255 } |
enum | KillReason { Interrupted = 0, Terminated = 1, Unknown = 255 } |
enum | ExceptionType { InvalidOpcode = 0, PageFault = 1, GeneralProtectionFault = 2, DivideByZero = 3, FpuError = 4, SpecialFpuError = 5, TerminalInput = 6, TerminalOutput = 7, Continue = 8, Stop = 9, Interrupt = 10, Quit = 11, Child = 12, Pipe = 13, Other = 255 } |
Public Member Functions | |
PosixSubsystem () | |
PosixSubsystem (PosixSubsystem &s) | |
PosixSubsystem (SubsystemType type) | |
virtual | ~PosixSubsystem () |
virtual void | acquire () |
Acquire full mutual exclusion for all Subsystem resources. More... | |
virtual void | release () |
virtual bool | kill (KillReason killReason, Thread *pThread) |
virtual void | threadException (Thread *pThread, ExceptionType eType) |
virtual void | sendSignal (Thread *pThread, int signal, bool yield=true) |
AlternateSignalStack & | getAlternateSignalStack () |
void | setAlternateSignalStack (AlternateSignalStack &s) |
void | setSignalHandler (size_t sig, SignalHandler *handler) |
SignalHandler * | getSignalHandler (size_t sig) |
void | exit (int code) NORETURN |
bool | copyDescriptors (PosixSubsystem *pSubsystem) |
size_t | getFd () |
void | allocateFd (size_t fdNum) |
void | freeFd (size_t fdNum) |
void | freeMultipleFds (bool bOnlyCloExec=false, size_t iFirst=0, size_t iLast=-1) |
FileDescriptor * | getFileDescriptor (size_t fd) |
void | addFileDescriptor (size_t fd, FileDescriptor *pFd) |
PosixSyncObject * | getSyncObject (size_t n) |
void | insertSyncObject (size_t n, PosixSyncObject *sem) |
void | removeSyncObject (size_t n) |
PosixThread * | getThread (size_t n) |
void | insertThread (size_t n, PosixThread *thread) |
void | removeThread (size_t n) |
Semaphore * | getThreadWaiter (void *n) |
void * | insertThreadWaiter (Semaphore *waiter) |
void | removeThreadWaiter (void *n) |
bool | checkAccess (FileDescriptor *pFileDescriptor, bool bRead, bool bWrite, bool bExecute) const |
virtual bool | invoke (const char *name, Vector< String > &argv, Vector< String > &env) |
virtual bool | invoke (const char *name, Vector< String > &argv, Vector< String > &env, SyscallState &state) |
virtual bool | invoke (File *originalFile, const String &originalName, Vector< String > &argv, Vector< String > &env) |
virtual bool | invoke (File *originalFile, const String &originalName, Vector< String > &argv, Vector< String > &env, SyscallState &state) |
virtual File * | findFile (const String &path, File *workingDir) |
Abi | getAbi () const |
void | setAbi (Abi which) |
Public Member Functions inherited from Subsystem | |
Subsystem () | |
Subsystem (const Subsystem &s) | |
Subsystem (SubsystemType type) | |
virtual | ~Subsystem () |
SubsystemType | getType () |
virtual void | setProcess (Process *p) |
Static Public Member Functions | |
static bool | checkAddress (uintptr_t addr, size_t extent, size_t flags) |
Static Public Attributes | |
static const size_t | SafeRegion = 0x0 |
static const size_t | SafeRead = 0x1 |
static const size_t | SafeWrite = 0x2 |
Private Member Functions | |
virtual void | threadRemoved (Thread *pThread) |
bool | loadElf (File *pFile, uintptr_t mappedAddress, uintptr_t &newAddress, uintptr_t &finalAddress, bool &relocated) |
bool | invoke (const char *name, Vector< String > &argv, Vector< String > &env, SyscallState *state) |
bool | invoke (File *originalFile, const String &originalName, Vector< String > &argv, Vector< String > &env, SyscallState *state) |
bool | parseShebang (File *pFile, File *&outFile, Vector< String > &argv) |
Private Attributes | |
Tree< size_t, SignalHandler * > | m_SignalHandlers |
UnlikelyLock | m_SignalHandlersLock |
Tree< size_t, FileDescriptor * > | m_FdMap |
size_t | m_NextFd |
UnlikelyLock | m_FdLock |
ExtensibleBitmap | m_FdBitmap |
size_t | m_LastFd |
int | m_FreeCount |
AlternateSignalStack | m_AltSigStack |
Tree< size_t, PosixSyncObject * > | m_SyncObjects |
Tree< size_t, PosixThread * > | m_Threads |
Tree< void *, Semaphore * > | m_ThreadWaiters |
size_t | m_NextThreadWaiter |
Abi | m_Abi |
bool | m_bAcquired |
Thread * | m_pAcquiredThread |
Spinlock | m_Lock |
LruCache< String, File * > | m_FindFileCache |
LRU cache for file lookups. Many usage patterns involve something like a stat() immediately followed by an open() or other similar system call. Rather than have both fully complete a filesystem traversal, we can cache the result and save time. | |
Filesystem * | m_pRootFs = nullptr |
Additional Inherited Members | |
Protected Attributes inherited from Subsystem | |
SubsystemType | m_Type |
Process * | m_pProcess |
Defines the compatibility layer for the POSIX Subsystem
Definition at line 105 of file PosixSubsystem.h.
enum PosixSubsystem::Abi |
ABI mode.
Definition at line 114 of file PosixSubsystem.h.
|
inline |
Default constructor
Definition at line 121 of file PosixSubsystem.h.
PosixSubsystem::PosixSubsystem | ( | PosixSubsystem & | s | ) |
Copy constructor
Definition at line 112 of file PosixSubsystem.cc.
References UnlikelyLock::acquire(), Tree< K, E >::begin(), Tree< K, E >::end(), UnlikelyLock::enter(), Tree< K, E >::insert(), UnlikelyLock::leave(), m_SignalHandlers, m_SignalHandlersLock, m_ThreadWaiters, and UnlikelyLock::release().
|
inline |
Parameterised constructor
Definition at line 134 of file PosixSubsystem.h.
|
virtual |
Default destructor
Definition at line 153 of file PosixSubsystem.cc.
References Spinlock::acquire(), acquire(), assert, Tree< K, E >::begin(), Tree< K, E >::clear(), Tree< K, E >::end(), freeMultipleFds(), Process::getAddressSpace(), Semaphore::getValue(), Processor::information(), MemoryMapManager::instance(), m_FreeCount, m_SignalHandlers, m_SyncObjects, PosixSubsystem::PosixThread::m_ThreadData, m_Threads, m_ThreadWaiters, Spinlock::release(), Semaphore::release(), release(), MemoryMapManager::releaseLock(), Processor::switchAddressSpace(), Semaphore::tryAcquire(), MemoryMapManager::unmapAllUnlocked(), and WARNING.
|
virtual |
Acquire full mutual exclusion for all Subsystem resources.
It is sometimes necessary to perform an operation that would require the entire Subsystem to be owned by a specific thread. For example, Subsystem termination often requires all other threads to exit the Subsystem's critical sections before it can complete.
This call allows that thread to acquire that mutual exclusion.
Reimplemented from Subsystem.
Definition at line 278 of file PosixSubsystem.cc.
References Spinlock::acquire(), UnlikelyLock::acquire(), Processor::information(), m_bAcquired, m_FdLock, m_Lock, m_pAcquiredThread, m_SignalHandlersLock, and Spinlock::release().
Referenced by ~PosixSubsystem().
void PosixSubsystem::addFileDescriptor | ( | size_t | fd, |
FileDescriptor * | pFd | ||
) |
Inserts a file descriptor
Definition at line 946 of file PosixSubsystem.cc.
References UnlikelyLock::acquire(), allocateFd(), freeFd(), Tree< K, E >::insert(), m_FdLock, m_FdMap, and UnlikelyLock::release().
void PosixSubsystem::allocateFd | ( | size_t | fdNum | ) |
Sets the given file descriptor as "in use".
Definition at line 781 of file PosixSubsystem.cc.
References UnlikelyLock::acquire(), m_FdBitmap, m_FdLock, m_NextFd, UnlikelyLock::release(), and ExtensibleBitmap::set().
Referenced by addFileDescriptor().
|
static |
Check whether a given region of memory is safe for the given operations.
This is important to do as we can get pointers from anywhere in the POSIX subsystem, and making sure they are sane and safe is crucial.
Definition at line 317 of file PosixSubsystem.cc.
References VirtualAddressSpace::CopyOnWrite, Dec, VirtualAddressSpace::getKernelStart(), VirtualAddressSpace::getMapping(), PhysicalMemoryManager::getPageSize(), VirtualAddressSpace::getUserStart(), Hex, Processor::information(), MemoryMapManager::instance(), VirtualAddressSpace::isMapped(), and VirtualAddressSpace::Write.
Referenced by WaitCleanup::terminated().
bool PosixSubsystem::copyDescriptors | ( | PosixSubsystem * | pSubsystem | ) |
Copies file descriptors from another subsystem
Definition at line 819 of file PosixSubsystem.cc.
References UnlikelyLock::acquire(), assert, Tree< K, E >::begin(), Tree< K, E >::end(), freeMultipleFds(), Tree< K, E >::insert(), m_FdBitmap, m_FdLock, m_FdMap, m_NextFd, UnlikelyLock::release(), and ExtensibleBitmap::set().
|
virtual |
Need to exit this process.
Implements Subsystem.
Definition at line 399 of file PosixSubsystem.cc.
References List< T, nodePoolSize >::begin(), Dec, List< T, nodePoolSize >::end(), List< T, nodePoolSize >::erase(), Thread::Exit, FATAL, freeMultipleFds(), Process::getExitStatus(), Process::getId(), Process::getParent(), Thread::getParent(), Thread::getStateLevel(), Process::getThread(), Process::getType(), Processor::information(), MemoryMapManager::instance(), Process::kill(), ProcessGroup::Leader, PosixProcess::Leader, m_FindFileCache, PosixProcess::Member, ProcessGroup::Members, NOTICE, Thread::ReleaseBlockingThread, Process::setExitStatus(), Processor::setInterrupts(), Thread::setUnwindState(), List< T, nodePoolSize >::size(), Subsystem::threadException(), Thread::unexpectedExit(), and MemoryMapManager::unmapAll().
Referenced by WaitCleanup::terminated().
Finds a file, performing any subsystem-specific logic as needed.
Implements Subsystem.
Definition at line 1169 of file PosixSubsystem.cc.
References assert, VFS::find(), LruCache< K, T, Slots >::get(), getAbi(), Process::getCwd(), Filesystem::getRoot(), VFS::instance(), VFS::lookupFilesystem(), m_FindFileCache, m_pRootFs, and LruCache< K, T, Slots >::store().
void PosixSubsystem::freeFd | ( | size_t | fdNum | ) |
Sets the given file descriptor as "available" and deletes the FileDescriptor linked to it.
Definition at line 796 of file PosixSubsystem.cc.
References UnlikelyLock::acquire(), ExtensibleBitmap::clear(), Tree< K, E >::lookup(), m_FdBitmap, m_FdLock, m_FdMap, m_LastFd, UnlikelyLock::release(), and Tree< K, E >::remove().
Referenced by addFileDescriptor().
void PosixSubsystem::freeMultipleFds | ( | bool | bOnlyCloExec = false , |
size_t | iFirst = 0 , |
||
size_t | iLast = -1 |
||
) |
Frees a range of descriptors (or only those marked FD_CLOEXEC)
Definition at line 860 of file PosixSubsystem.cc.
References UnlikelyLock::acquire(), assert, List< T, nodePoolSize >::begin(), Tree< K, E >::begin(), ExtensibleBitmap::clear(), Tree< K, E >::clear(), List< T, nodePoolSize >::end(), Tree< K, E >::end(), FileDescriptor::fdflags, m_FdBitmap, m_FdLock, m_FdMap, m_LastFd, List< T, nodePoolSize >::pushBack(), UnlikelyLock::release(), and Tree< K, E >::remove().
Referenced by copyDescriptors(), exit(), invoke(), and ~PosixSubsystem().
|
inline |
Retrieves the currently-active ABI for the subsystem.
Definition at line 510 of file PosixSubsystem.h.
Referenced by findFile(), and WaitCleanup::terminated().
|
inline |
Grabs the alternate signal stack
Definition at line 203 of file PosixSubsystem.h.
size_t PosixSubsystem::getFd | ( | ) |
Returns the first available file descriptor.
Note: POSIX requires open()/accept()/etc to be safe during a signal handler, which requires us to not allow signals during these file descriptor calls. They cannot re-enter as they take process-specific locks.
Definition at line 753 of file PosixSubsystem.cc.
References UnlikelyLock::acquire(), m_FdBitmap, m_FdLock, m_LastFd, m_NextFd, UnlikelyLock::release(), ExtensibleBitmap::set(), and ExtensibleBitmap::test().
FileDescriptor * PosixSubsystem::getFileDescriptor | ( | size_t | fd | ) |
Gets a pointer to a FileDescriptor object from an fd number
Definition at line 931 of file PosixSubsystem.cc.
References UnlikelyLock::enter(), UnlikelyLock::leave(), Tree< K, E >::lookup(), m_FdLock, and m_FdMap.
|
inline |
Gets a signal handler
Definition at line 276 of file PosixSubsystem.h.
References NORETURN.
Referenced by kill(), and sendSignal().
|
inline |
Gets a synchronisation object given a descriptor
Definition at line 334 of file PosixSubsystem.h.
|
inline |
Gets a thread given a descriptor
Definition at line 439 of file PosixSubsystem.h.
|
inline |
Gets a thread waiter object given a descriptor
Definition at line 462 of file PosixSubsystem.h.
|
inline |
Inserts a synchronisation object given a descriptor
Definition at line 340 of file PosixSubsystem.h.
|
inline |
Inserts a thread given a descriptor and a Thread
Definition at line 445 of file PosixSubsystem.h.
|
inline |
Inserts a thread waiter object, returns a descriptor
Definition at line 468 of file PosixSubsystem.h.
|
virtual |
Invokes the given command (thread mechanism).
Implements Subsystem.
Definition at line 1231 of file PosixSubsystem.cc.
Referenced by invoke(), and parseShebang().
|
virtual |
Invokes the given command (SyscallState mechanism).
Implements Subsystem.
Definition at line 1237 of file PosixSubsystem.cc.
References invoke().
|
virtual |
Invokes the given file (thread mechanism).
Implements Subsystem.
Definition at line 1378 of file PosixSubsystem.cc.
References invoke().
|
virtual |
Invokes the given file (SyscallState mechanism).
Implements Subsystem.
Definition at line 1385 of file PosixSubsystem.cc.
References invoke().
|
private |
Invokes the given command - actual implementation.
Definition at line 1392 of file PosixSubsystem.cc.
References VFS::checkAccess(), DynamicLinker::checkInterpreter(), Vector< T >::count(), Process::description(), Thread::detach(), VirtualAddressSpace::Execute, Elf::extractEntryPoint(), RangeList< T, Reversed >::free(), freeMultipleFds(), Process::getAddressSpace(), VirtualAddressSpace::getDynamicEnd(), Process::getDynamicSpaceAllocator(), VirtualAddressSpace::getDynamicStart(), File::getName(), Process::getNumThreads(), PhysicalMemoryManager::getPageSize(), Process::getSpaceAllocator(), Thread::getStateLevel(), Process::getThread(), Process::getType(), Process::getUserId(), VirtualAddressSpace::getUserReservedStart(), VirtualAddressSpace::getUserStart(), Processor::information(), MemoryMapManager::instance(), Processor::jumpUser(), loadElf(), MemoryMapManager::mapAnon(), MemoryMapManager::mapFile(), parseShebang(), Thread::popState(), File::read(), Process::recordTime(), Thread::resetTlsBase(), VirtualAddressSpace::revertToKernelAddressSpace(), Processor::setInterrupts(), MemoryMapManager::setPermissions(), Thread::state(), MemoryMapManager::unmap(), MemoryMapManager::unmapAll(), and Elf::validate().
|
virtual |
A thread needs to be killed!
Implements Subsystem.
Definition at line 510 of file PosixSubsystem.cc.
References ERROR, Process::getId(), Thread::getParent(), getSignalHandler(), Process::getType(), Processor::information(), Scheduler::instance(), PosixSubsystem::SignalHandler::pEvent, Thread::sendEvent(), Processor::setInterrupts(), and Scheduler::yield().
|
private |
Load an ELF's PT_LOAD sections into the address space.
Definition at line 990 of file PosixSubsystem.cc.
References ERROR, File::getName(), PhysicalMemoryManager::getPageSize(), Hex, Processor::information(), MemoryMapManager::instance(), MemoryMapManager::mapAnon(), and MemoryMapManager::mapFile().
Referenced by invoke().
|
private |
Parse a file for a possible shebang line.
Definition at line 1244 of file PosixSubsystem.cc.
References Vector< T >::begin(), Vector< T >::count(), Symlink::followLink(), Symlink::fromFile(), File::getFullPath(), invoke(), File::isDirectory(), File::isSymlink(), Vector< T >::popBack(), Vector< T >::pushFront(), and File::read().
Referenced by invoke().
|
virtual |
Release mutual exclusion acquired via acquire().
Reimplemented from Subsystem.
Definition at line 304 of file PosixSubsystem.cc.
References Spinlock::acquire(), m_bAcquired, m_FdLock, m_Lock, m_pAcquiredThread, m_SignalHandlersLock, Spinlock::release(), and UnlikelyLock::release().
Referenced by ~PosixSubsystem().
|
inline |
Removes a semaphore given a descriptor
Definition at line 353 of file PosixSubsystem.h.
|
inline |
Removes a thread given a descriptor
Definition at line 455 of file PosixSubsystem.h.
|
inline |
Removes a thread waiter object given a descriptor
Definition at line 479 of file PosixSubsystem.h.
|
virtual |
Send a POSIX signal to the given thread.
Definition at line 648 of file PosixSubsystem.cc.
References Dec, ERROR, Process::getId(), Thread::getId(), Thread::getParent(), getSignalHandler(), Thread::hasEvent(), Processor::information(), Scheduler::instance(), NOTICE, PosixSubsystem::SignalHandler::pEvent, Thread::sendEvent(), WARNING, and Scheduler::yield().
Referenced by IoEvent::IoEvent(), VirtualTerminalManager::setTerminalMode(), IntervalTimer::signal(), and threadException().
|
inline |
Switch the ABI of the subsystem to the specified choice.
Definition at line 516 of file PosixSubsystem.h.
Referenced by PosixSyscallManager::syscall().
|
inline |
Sets the alternate signal stack, if possible
Definition at line 209 of file PosixSubsystem.h.
void PosixSubsystem::setSignalHandler | ( | size_t | sig, |
SignalHandler * | handler | ||
) |
Sets a signal handler
Definition at line 714 of file PosixSubsystem.cc.
References UnlikelyLock::acquire(), m_SignalHandlers, m_SignalHandlersLock, UnlikelyLock::release(), and PosixSubsystem::SignalHandler::sig.
|
virtual |
A thread has thrown an exception!
Reimplemented from Subsystem.
Definition at line 556 of file PosixSubsystem.cc.
References Dec, ERROR, Process::getId(), Thread::getId(), Thread::getParent(), and sendSignal().
|
privatevirtual |
Notifies the subsystem that the given thread has been removed.
Reimplemented from Subsystem.
Definition at line 965 of file PosixSubsystem.cc.
References VFS::checkAccess(), FileDescriptor::file, m_Threads, and Semaphore::release().
|
private |
ABI for the subsystem This affects syscall parameters and the behaviors of some syscalls.
Definition at line 595 of file PosixSubsystem.h.
|
private |
Alternate signal stack - if defined, used instead of a system-defined stack
Definition at line 576 of file PosixSubsystem.h.
|
private |
Are we acquired?
Definition at line 600 of file PosixSubsystem.h.
|
private |
File descriptors used by this process
Definition at line 563 of file PosixSubsystem.h.
Referenced by allocateFd(), copyDescriptors(), freeFd(), freeMultipleFds(), and getFd().
|
private |
Lock to guard the next file descriptor while it is being changed.
Definition at line 559 of file PosixSubsystem.h.
Referenced by acquire(), addFileDescriptor(), allocateFd(), copyDescriptors(), freeFd(), freeMultipleFds(), getFd(), getFileDescriptor(), and release().
|
private |
The file descriptor map. Maps number to pointers, the type of which is decided by the subsystem.
Definition at line 551 of file PosixSubsystem.h.
Referenced by addFileDescriptor(), copyDescriptors(), freeFd(), freeMultipleFds(), and getFileDescriptor().
|
private |
Number of times freed
Definition at line 571 of file PosixSubsystem.h.
Referenced by ~PosixSubsystem().
|
private |
Last known unallocated descriptor
Definition at line 567 of file PosixSubsystem.h.
Referenced by freeFd(), freeMultipleFds(), and getFd().
|
private |
Safety spinlock for mutual exclusion in acquire().
Definition at line 610 of file PosixSubsystem.h.
|
private |
The next available file descriptor.
Definition at line 555 of file PosixSubsystem.h.
Referenced by allocateFd(), copyDescriptors(), and getFd().
|
private |
Which thread acquired?
Definition at line 605 of file PosixSubsystem.h.
|
private |
Cached lookup of the root filesystem.
Definition at line 621 of file PosixSubsystem.h.
Referenced by findFile().
|
private |
Signal handlers
Definition at line 542 of file PosixSubsystem.h.
Referenced by PosixSubsystem(), setSignalHandler(), and ~PosixSubsystem().
|
private |
A lock for access to the signal handlers tree
Definition at line 545 of file PosixSubsystem.h.
Referenced by acquire(), PosixSubsystem(), release(), and setSignalHandler().
|
private |
Links some file descriptors to PosixSyncObjects.
Definition at line 580 of file PosixSubsystem.h.
Referenced by ~PosixSubsystem().
|
private |
Links some thread handles to Threads.
Definition at line 584 of file PosixSubsystem.h.
Referenced by threadRemoved(), and ~PosixSubsystem().
Links waiter objects to Semaphores.
Definition at line 588 of file PosixSubsystem.h.
Referenced by PosixSubsystem(), and ~PosixSubsystem().
|
static |
Sanitise flags.
Definition at line 109 of file PosixSubsystem.h.