[*] Some WTF

[*] Use waitpid instead of wait3 (BSD, now deprecated by POSIX)
[*] Win32 / x86_32: I guess the file map maximum size should be the same as 64bit since it lets us? we need this span constraint to be the entire file or less.
[*] Improved AuProcess UNIX signal safety
[*] Comments
[+] Secret API: RuntimeCollectMemory
This commit is contained in:
Reece Wilson 2024-10-12 16:28:18 +01:00
parent 02826d2365
commit b5c4271807
7 changed files with 99 additions and 132 deletions

View File

@ -22,13 +22,22 @@ namespace Aurora
{ {
// Now you should hopefully need not worry about the 3 Bill-ion Shaftsoft CreateFile[2][FromApp][W/A] variants... // Now you should hopefully need not worry about the 3 Bill-ion Shaftsoft CreateFile[2][FromApp][W/A] variants...
// ...and the varying degress of dwFlags/dwAttrs support. // ...and the varying degress of dwFlags/dwAttrs support.
AUKN_SYM HANDLE Win32Open(LPCWSTR lpFileName, AUKN_SYM HANDLE Win32Open(LPCWSTR lpFileName,
DWORD dwDesiredAccess = GENERIC_READ | GENERIC_WRITE, DWORD dwDesiredAccess = GENERIC_READ | GENERIC_WRITE,
DWORD dwShareMode = FILE_SHARE_READ, DWORD dwShareMode = FILE_SHARE_READ,
bool bInherit = false, bool bInherit = false,
DWORD dwCreationDisposition = 0, DWORD dwCreationDisposition = 0,
DWORD dwFlags = 0, DWORD dwFlags = 0,
DWORD dwAttributes = 0 DWORD dwAttributes = 0 // (0 = FILE_ATTRIBUTE_NORMAL)
);
AUKN_SYM HANDLE Win32Open2(LPCWSTR lpFileName,
DWORD dwDesiredAccess = GENERIC_READ | GENERIC_WRITE,
DWORD dwShareMode = FILE_SHARE_READ,
LPSECURITY_ATTRIBUTES lpSecurityAttributes = NULL,
DWORD dwCreationDisposition = 0,
DWORD dwFlags = 0,
DWORD dwAttributes = 0 // (0 = FILE_ATTRIBUTE_NORMAL)
); );
} }

View File

@ -50,8 +50,7 @@ namespace Aurora
template <typename... T> template <typename... T>
long syscallFuckYou(T &&... args) long syscallFuckYou(T &&... args)
{ {
// sysdeps/unix/sysv/linux/x86_64/syscall.S // xref: glibc://sysdeps/unix/sysv/linux/x86_64/syscall.S
// Fuck Freetards
long iFuckResult = syscall(AuForward<T &&>(args)...); long iFuckResult = syscall(AuForward<T &&>(args)...);
#if defined(AURORA_IS_GLIBC) #if defined(AURORA_IS_GLIBC)
if (iFuckResult == -1 && if (iFuckResult == -1 &&
@ -76,8 +75,7 @@ namespace Aurora
// I guess it's like the other FUTEX issue where every single thead and every single process under Linux is bound to one ABI defined by glib, // I guess it's like the other FUTEX issue where every single thead and every single process under Linux is bound to one ABI defined by glib,
// and the kernels stance on the matter is, I quote "must only be changed if the change is first communicated with the glibc folks." // and the kernels stance on the matter is, I quote "must only be changed if the change is first communicated with the glibc folks."
// That meaning, it doesn't matter because they're just going to half-ass things together holding hands. // That meaning, it doesn't matter because they're just going to half-ass things together holding hands.
// Daily reminder, Lin-shit is half-assed HW abstraction layer held together with forced driver source sharing and glibc+freeedesktop hopes and dreams. // Daily reminder, Linshit is half-assed HW abstraction layer held together with forced driver source sharing and glibc+freeedesktop hopes and dreams.
// Fucking retards, I swear
} }
int pidfd_getfd(int pidfd, int targetfd, int pidfd_getfd(int pidfd, int targetfd,
@ -429,4 +427,37 @@ namespace Aurora
{ {
futex_wake((AuUInt32 *)pAddress, 1); futex_wake((AuUInt32 *)pAddress, 1);
} }
// TODO: transition the externally linked POSIX-like symbols down to internally linked symbols.
// GNU versioning is terrible and halfassed.
// arbitrary symbols of posix and the c[rt] spuriously change their required glibc version on a dime.
// this thereby requires the users' platform to update a write-protected distro binary (/???/ld-???.so) of a min-ver linker to be paired with at least min-ver of glibc as specified by a "portable" elf section.
// not only must glibc extensions be dynamically loaded, we will probably end up implementing a bit of posix over a generic crt-provided syscall func, what with this GNU stupidity still plaguing everything Linux.
// build chains contaminated with glibc are hopeless without our portable glibc post-build scripts. also worthy of note, musl doesnt implement some tls bits and some dumb string function nvidia requires.
// no matter what, we need to expect glibc, aim for musl, and know that vendor tie in means we're almost (not really) forced into using glibc in prod *
// ( *: prebuilt arm gpu binaries, prebuilt nvidia drivers, cisco signed openh264 with prepaid royalties, etc. we really shouldn't need binary patches or supplemental symbols to link these. )
// ps: just to prove how fucking asinine glibc is:
// pthread_setspecific@GLIBC_2.34 pthread_attr_setstacksize@GLIBC_2.34 (2.38 = 2024/Q1, 2.34 = 2021/Q3, 2.33 = 2021/Q1, 2.32 = 2020/Q3)
// pthread_sigmask@GLIBC_2.32 __isoc23_strtoull@GLIBC_2.38
// __isoc23_sscanf@GLIBC_2.38 dlopen@GLIBC_2.34
// dladdr@GLIBC_2.34 pthread_cancel@GLIBC_2.34
// __isoc23_strtoll@GLIBC_2.38 pthread_cond_timedwait@GLIBC_2.3.2
// __isoc23_wcstoul@GLIBC_2.38 pthread_getspecific@GLIBC_2.34
// pthread_join@GLIBC_2.34 pthread_key_create@GLIBC_2.34
// stat@GLIBC_2.33 fstat@GLIBC_2.33
// __isoc23_strtoll_l@GLIBC_2.38 shm_open@GLIBC_2.34
// gettid@GLIBC_2.30 __isoc23_wcstoll@GLIBC_2.38
// pthread_once@GLIBC_2.34 pthread_setaffinity_np@GLIBC_2.34
// dlsym@GLIBC_2.34 pthread_create@GLIBC_2.34
// pthread_setname_np@GLIBC_2.34 __isoc23_vsscanf@GLIBC_2.38
// __isoc23_strtoull_l@GLIBC_2.38 pthread_cond_destroy@GLIBC_2.3.2
// __isoc23_wcstol@GLIBC_2.38 __isoc23_wcstoull@GLIBC_2.38
// __isoc23_strtoul@GLIBC_2.38 lstat@GLIBC_2.33
// pthread_kill@GLIBC_2.34 __isoc23_strtol@GLIBC_2.38
// ( 2024/Q4 AuroraRuntime.Stage.Linux.x86_64.so )
// ( built under a glibc root )
// ( 34 bad imports out of 306 )
//
// wanna dlopen? wanna stat a file? call a pthread function of args: {pthread handle, const char *}? you know what? do you even know your thread id? ...i mean, wanna get your current posix process id?
// sorry, that'll be a 2022 glibc binary, a forced distro update, bash scripts to run an ELF binary of CWD != bindir, and a fuck you + pocket sand in the eyes + dagger in the ass for choosing GHANNUUU / FREEDUM
} }

View File

@ -802,96 +802,22 @@ namespace Aurora
SECURITY_ATTRIBUTES attrs {}; SECURITY_ATTRIBUTES attrs {};
attrs.nLength = sizeof(attrs); attrs.nLength = sizeof(attrs);
attrs.bInheritHandle = bInherit ? TRUE : FALSE; attrs.bInheritHandle = bInherit ? TRUE : FALSE;
return Win32Open2(lpFileName,
bool bSpecialFlags = (dwFlags & 0x4ffff7); dwDesiredAccess,
bool bSpecialAttrs = (dwAttributes & 0xFFB00008); dwShareMode,
&attrs,
if (!pCreateFile2W) dwCreationDisposition,
{ dwFlags,
if (bSpecialFlags) dwAttributes);
{
SysPushErrorFeatureMissing("Do not use Windows8+ attributes/flags under Win32Open");
return INVALID_HANDLE_VALUE;
}
if (bSpecialAttrs)
{
SysPushErrorFeatureMissing("Do not use Windows8+ attributes/flags under Win32Open");
return INVALID_HANDLE_VALUE;
}
}
if (!dwAttributes)
{
dwAttributes = FILE_ATTRIBUTE_NORMAL;
}
if (pCreateFileW &&
!bSpecialFlags &&
!bSpecialAttrs)
{
return pCreateFileW(lpFileName,
dwDesiredAccess,
dwShareMode,
&attrs,
dwCreationDisposition,
dwFlags | dwAttributes,
NULL);
}
if (pCreateFile2W)
{
_CREATEFILE2_EXTENDED_PARAMETERS params {};
bool bRead {};
HANDLE hHandle {};
params.dwSize = sizeof(_CREATEFILE2_EXTENDED_PARAMETERS);
params.dwFileFlags = dwFlags;
params.dwFileAttributes = dwAttributes;
params.lpSecurityAttributes = &attrs;
if ((bRead = (::wcscmp(lpFileName, L"CONIN$") == 0)) ||
(::wcscmp(lpFileName, L"CONOUT$") == 0) ||
(::wcscmp(lpFileName, L"CONERR$") == 0))
{
if (!bRead)
{
dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
}
else
{
dwDesiredAccess = GENERIC_READ;
}
if ((hHandle = pCreateFile2W(lpFileName,
dwDesiredAccess,
dwShareMode,
dwCreationDisposition,
&params)) != INVALID_HANDLE_VALUE)
{
return hHandle;
}
lpFileName = L"CON";
}
return pCreateFile2W(lpFileName,
dwDesiredAccess,
dwShareMode,
dwCreationDisposition,
&params);
}
return INVALID_HANDLE_VALUE;
} }
HANDLE Win32Open2(LPCWSTR lpFileName, HANDLE Win32Open2(LPCWSTR lpFileName,
DWORD dwDesiredAccess, DWORD dwDesiredAccess,
DWORD dwShareMode, DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes, LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDisposition, DWORD dwCreationDisposition,
DWORD dwFlags, DWORD dwFlags,
DWORD dwAttributes) DWORD dwAttributes)
{ {
bool bSpecialFlags = (dwFlags & 0x4ffff7); bool bSpecialFlags = (dwFlags & 0x4ffff7);
bool bSpecialAttrs = (dwAttributes & 0xFFB00008); bool bSpecialAttrs = (dwAttributes & 0xFFB00008);

View File

@ -252,6 +252,11 @@ namespace Aurora
Grug::WaitForGrugTick(); Grug::WaitForGrugTick();
} }
AUKN_SYM void RuntimeCollectMemory()
{
mi_collect(true);
}
void RuntimeLateClean() void RuntimeLateClean()
{ {
::RuntimeLateClean(); ::RuntimeLateClean();

View File

@ -180,13 +180,8 @@ namespace Aurora::Process
hFileMap = pCreateFileMappingA((HANDLE)pIOHandle->GetOSHandle(), hFileMap = pCreateFileMappingA((HANDLE)pIOHandle->GetOSHandle(),
nullptr, nullptr,
pageAttributes, pageAttributes,
#if defined(AURORA_IS_64BIT) AuBitsToHigher(AuUInt64(uLength) + uOffset),
AuBitsToHigher(uLength + uOffset), AuBitsToLower(AuUInt64(uLength) + uOffset),
AuBitsToLower(uLength + uOffset),
#else
0,
uLength,
#endif
nullptr); nullptr);
if ((hFileMap == INVALID_HANDLE_VALUE) || if ((hFileMap == INVALID_HANDLE_VALUE) ||
(!hFileMap)) (!hFileMap))

View File

@ -457,13 +457,8 @@ namespace Aurora::Process
hFileMap = pCreateFileMappingA((HANDLE)pIOHandle->GetOSHandle(), hFileMap = pCreateFileMappingA((HANDLE)pIOHandle->GetOSHandle(),
nullptr, nullptr,
pageAttributes, pageAttributes,
#if defined(AURORA_IS_64BIT) AuBitsToHigher(AuUInt64(uLength) + uOffset),
AuBitsToHigher(uLength + uOffset), AuBitsToLower(AuUInt64(uLength) + uOffset),
AuBitsToLower(uLength + uOffset),
#else
0,
uLength,
#endif
nullptr); nullptr);
if ((hFileMap == INVALID_HANDLE_VALUE) || if ((hFileMap == INVALID_HANDLE_VALUE) ||
(!hFileMap)) (!hFileMap))

View File

@ -49,7 +49,7 @@
namespace Aurora::Processes namespace Aurora::Processes
{ {
static AuRWLock gRWLock; static AuRWRenterableLock gRWLock;
static AuHashMap<pid_t, ProcessImpl *> gPidLookupMap; static AuHashMap<pid_t, ProcessImpl *> gPidLookupMap;
struct ProcessAliveLoopSource : AuLoop::LSEvent struct ProcessAliveLoopSource : AuLoop::LSEvent
@ -58,6 +58,8 @@ namespace Aurora::Processes
virtual AuLoop::ELoopSource GetType() override; virtual AuLoop::ELoopSource GetType() override;
}; };
static void ConsumeChildDeathQueue();
ProcessAliveLoopSource::ProcessAliveLoopSource() : LSEvent(false, false, true) ProcessAliveLoopSource::ProcessAliveLoopSource() : LSEvent(false, false, true)
{} {}
@ -66,7 +68,6 @@ namespace Aurora::Processes
return AuLoop::ELoopSource::eProcessDead; return AuLoop::ELoopSource::eProcessDead;
} }
ProcessImpl::ProcessImpl(StartupParameters &&params) : startup_(AuMove(params)) ProcessImpl::ProcessImpl(StartupParameters &&params) : startup_(AuMove(params))
{ {
AuIOFS::NormalizePath(this->startup_.process, this->startup_.process); AuIOFS::NormalizePath(this->startup_.process, this->startup_.process);
@ -104,15 +105,6 @@ namespace Aurora::Processes
{ {
AU_LOCK_GUARD(gRWLock->AsWritable()); AU_LOCK_GUARD(gRWLock->AsWritable());
if (this->alive_)
{
if (this->type_ == ESpawnType::eSpawnThreadLeader)
{
::kill(this->pidt_, SIGCONT);
}
}
AuTryRemove(gPidLookupMap, this->pidt_); AuTryRemove(gPidLookupMap, this->pidt_);
} }
@ -132,6 +124,8 @@ namespace Aurora::Processes
bool ProcessImpl::HasExited() bool ProcessImpl::HasExited()
{ {
ConsumeChildDeathQueue();
return this->bHasExited; return this->bHasExited;
} }
@ -197,6 +191,8 @@ namespace Aurora::Processes
{ {
AU_LOCK_GUARD(gRWLock->AsReadable()); AU_LOCK_GUARD(gRWLock->AsReadable());
ConsumeChildDeathQueue();
if (this->alive_) if (this->alive_)
{ {
if (::kill(this->pidt_, SIGTERM) == 0) if (::kill(this->pidt_, SIGTERM) == 0)
@ -212,6 +208,8 @@ namespace Aurora::Processes
{ {
AU_LOCK_GUARD(gRWLock->AsReadable()); AU_LOCK_GUARD(gRWLock->AsReadable());
ConsumeChildDeathQueue();
if (this->alive_) if (this->alive_)
{ {
return ::kill(this->pidt_, SIGKILL) == 0; return ::kill(this->pidt_, SIGKILL) == 0;
@ -870,8 +868,6 @@ namespace Aurora::Processes
static void HandleChildTermiantion(pid_t pid, int code) static void HandleChildTermiantion(pid_t pid, int code)
{ {
AU_LOCK_GUARD(gRWLock->AsReadable());
auto handler = gPidLookupMap.find(pid); auto handler = gPidLookupMap.find(pid);
if (handler == gPidLookupMap.end()) if (handler == gPidLookupMap.end())
{ {
@ -884,23 +880,33 @@ namespace Aurora::Processes
} }
} }
static void SigChldHandler(int) void ConsumeChildDeathQueue()
{ {
int code; int code;
pid_t pid; pid_t pid;
while (true) auto pLock = gRWLock->AsReadable();
if (!pLock->TryLock())
{ {
pid = wait3(&code, WNOHANG, nullptr); return;
}
if ((pid == 0) || while ((pid = waitpid((pid_t)-1, &code, WNOHANG)))
(pid == -1)) {
if (pid == (pid_t)-1)
{ {
break; break;
} }
HandleChildTermiantion(pid, code); HandleChildTermiantion(pid, code);
} }
pLock->Unlock();
}
static void SigChldHandler(int)
{
ConsumeChildDeathQueue();
} }
void InitUnix() void InitUnix()