180 enum class DescriptorDuplicationResult { Success, BadSource, TargetBusy };
183 static const size_t SafeRegion = 0x0;
184 static const size_t SafeRead = 0x1;
185 static const size_t SafeWrite = 0x2;
186 static const size_t SafeExecute = 0x4;
192 static constexpr size_t LinuxPrivateSignalFirst = 32;
193 static constexpr size_t MaximumSupportedSignal = 64;
194 static constexpr size_t SignalDispositionCount = MaximumSupportedSignal + 1;
206 m_SignalHandlersLock(),
218 m_NextThreadWaiter(0),
219 m_ImageMetadataLock(),
224 m_pAcquiredThread(nullptr) {}
233 m_SignalHandlersLock(),
245 m_NextThreadWaiter(0),
246 m_ImageMetadataLock(),
251 m_pAcquiredThread(nullptr) {}
257 bool executablePath(
String& result)
const;
262 return m_TraceContext;
264 bool tracePolicyAllowed()
const {
265 return affinityPolicyAllowed() && m_Abi == LinuxAbi;
269 bool traceException(
Thread&,
int& signal, InterruptState&, ExceptionType, uintptr_t, uintptr_t);
270 TraceStatus prepareTraceSignal(
Thread&,
int signal, int32_t pid, uint32_t uid,
297 static bool checkAddress(uintptr_t addr,
size_t extent,
size_t flags);
305 static bool checkedUserBufferSize(
size_t count,
size_t elementSize,
size_t& extent);
307 static constexpr size_t MaximumExecArgumentBytes = 131072;
314 static bool checkUserAddressRange(uintptr_t addr,
size_t count,
size_t elementSize,
315 size_t* extent =
nullptr);
318 static bool checkUserBuffer(uintptr_t addr,
size_t count,
size_t elementSize,
size_t flags,
319 size_t* extent =
nullptr);
327 static bool copyFromUser(
void* destination,
const void* source,
size_t count,
328 size_t elementSize = 1);
331 static bool copyToUser(
void* destination,
const void* source,
size_t count,
332 size_t elementSize = 1);
337 static size_t readCachedFile(
File& file, uint64_t offset,
void* destination,
size_t count);
339 enum UserStringResult { UserStringSuccess, UserStringBadAddress, UserStringTooLong };
342 static UserStringResult copyUserString(
const char* userString,
String& copy,
size_t maxLength);
345 virtual bool kill(KillReason killReason,
Thread* pThread);
349 InterruptState* pState =
nullptr, uintptr_t faultAddress = 0,
350 uintptr_t errorCode = 0);
353 uintptr_t errorCode)
override;
356 virtual void sendSignal(
Thread* pThread,
int signal,
bool yield =
true,
357 bool processDirected =
false);
361 SignalHandler() : sig(255), pEvent(0), sigMask(0), flags(0), restorer(0), type(0) {}
416 SignalDisposition() : handler(0), signalMask(0), flags(0), restorer(0), type(1) {}
425 enum class SignalDeliveryResult { Unavailable, Ignored, Rejected, Queued, Full };
428 void setSignalHandler(
size_t sig, SignalHandler* handler);
430 bool admitLegacyUserSignals();
433 bool affinityPolicyAllowed()
const {
434 return m_CallbackSchedulingDomain != CallbackSchedulingDomain::LegacySignals;
436 void recordAffinityPolicyUse() {
437 m_CallbackSchedulingDomain = CallbackSchedulingDomain::Affinity;
444 void resetSignalHandlersForExec(
Thread* thread,
445 SignalHandler*
const handlers[SignalDispositionCount]);
448 bool getSignalDisposition(
size_t sig, SignalDisposition& disposition,
bool beginDelivery =
false);
451 SignalDeliveryResult queueSignalDelivery(
452 Thread* target,
size_t sig, uint32_t* flags =
nullptr, int32_t signalCode = 0,
453 bool processDirected =
false, uint64_t signalValue = 0,
460 uint64_t generation = 0;
466 void invalidateUserImage();
470 return m_PendingSignals;
472 Mutex& pendingSignalLock() {
473 return m_PendingSignals->lock;
476 return m_PendingSignals->changed;
482 return m_AdvisoryOwner;
486 return m_MemoryLockAccount;
491 if (sig > MaximumSupportedSignal) {
494 m_SignalHandlersLock.enter();
496 m_SignalHandlersLock.leave();
500 void exit(
int code, ExitCause cause = ExitCause::Normal)
NORETURN;
506 size_t getFd(
size_t minimum = 0);
509 void allocateFd(
size_t fdNum);
513 void freeFd(
size_t fdNum);
516 void freeMultipleFds(
bool bOnlyCloExec =
false,
size_t iFirst = 0,
size_t iLast = -1);
528 bool acquireNextFileDescriptor(
size_t minimum,
size_t& fd,
DescriptorLease& descriptor);
531 bool descriptorMatchesOpenDescription(
size_t fd,
541 bool closeFileDescriptor(
size_t fd,
const DescriptorLease& descriptor);
554 DescriptorDuplicationResult duplicateFileDescriptor(
size_t source,
size_t target,
585 return m_SyncObjects.lookup(n);
592 m_SyncObjects.remove(n);
596 m_SyncObjects.insert(n, sem);
603 m_SyncObjects.remove(n);
611 void (*destructor)(
void*);
647 return m_ThreadData.
lookup(key);
663 if (m_ThreadData.
lookup(key))
665 m_ThreadData.
insert(key, info);
682 return m_Threads.lookup(n);
691 return m_Threads.insert(n, thread);
701 return m_ThreadWaiters.lookup(n);
706 void* descriptor =
reinterpret_cast<void*
>(m_NextThreadWaiter++);
707 Semaphore* t = m_ThreadWaiters.lookup(descriptor);
709 m_ThreadWaiters.remove(descriptor);
710 m_ThreadWaiters.insert(descriptor,
waiter);
716 m_ThreadWaiters.remove(n);
719 bool checkAccess(
const DescriptorLease& pFileDescriptor,
bool bRead,
bool bWrite,
720 bool bExecute)
const;
721 uint64_t filesystemAccess(
const FilesystemPathRef* ancestry,
size_t count)
const override;
722 bool filesystemConstrained()
const override;
725 size_t destinationCount)
const override;
732 SyscallState& state);
743 Vector<String>& env, SyscallState& state,
bool descriptorPathInaccessible);
747 bool descriptorPathInaccessible =
false);
751 bool followFinal =
false);
765 struct ExecutableImage;
767 static constexpr size_t FdBuckets = 16;
769 void acquireFdLock();
770 void publishFdEntry(
size_t fd);
771 void publishFdEntries();
776 void clearChildTid(
Thread* thread);
780 bool prepareExecutable(
File* pFile, ExecutableImage& image,
bool isInterpreter);
783 bool loadElf(
const ExecutableImage& image, uintptr_t& loadBias);
789 Vector<String>& env, SyscallState* state,
bool descriptorPathInaccessible =
false,
793 bool parseShebang(
File* pFile,
String& interpreter,
String& optionalArgument,
794 bool& hasOptionalArgument);
802 enum class CallbackSchedulingDomain { Unrestricted, LegacySignals, Affinity };
803 CallbackSchedulingDomain m_CallbackSchedulingDomain = CallbackSchedulingDomain::Unrestricted;
810 uint64_t m_UserImageGeneration = 0;
811 bool m_UserImageActive =
false;
850 size_t m_NextThreadWaiter;
851 mutable Mutex m_ImageMetadataLock;