255 lines
6.1 KiB
C++
Executable File
255 lines
6.1 KiB
C++
Executable File
/***
|
|
Copyright (C) 2024 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
|
|
|
File: AuProcAddresses.UNIX.cpp
|
|
Date: 2024-3-5
|
|
Author: Reece
|
|
***/
|
|
#include "RuntimeInternal.hpp"
|
|
#include "AuProcAddresses.UNIX.hpp"
|
|
#if defined(AURORA_IS_LINUX_DERIVED)
|
|
#include "AuProcAddresses.Linux.hpp"
|
|
#endif
|
|
|
|
#include <Source/Debug/ExceptionWatcher.Unix.hpp>
|
|
|
|
#include <unistd.h>
|
|
#include <sys/mman.h>
|
|
|
|
namespace Aurora::Process
|
|
{
|
|
void PosixForkResetLocks();
|
|
}
|
|
|
|
namespace Aurora::Memory
|
|
{
|
|
AuUInt32 RoundPageUp(AuUInt32 value);
|
|
}
|
|
|
|
namespace Aurora
|
|
{
|
|
void PosixInitAddresses()
|
|
{
|
|
#if defined(AURORA_OWNS_SYMBOLS_FOR_UNWIND)
|
|
punw_getcontext = unw_getcontext;
|
|
punw_get_reg = unw_get_reg;
|
|
punw_get_proc_name = unw_get_proc_name;
|
|
punw_step = unw_step;
|
|
punw_init_local = unw_init_local;
|
|
#else
|
|
#if defined(RTLD_DEFAULT)
|
|
punw_getcontext = (decltype(punw_getcontext))dlsym(RTLD_DEFAULT, "unw_getcontext");
|
|
punw_get_reg = (decltype(punw_get_reg))dlsym(RTLD_DEFAULT, "unw_get_reg");
|
|
punw_get_proc_name = (decltype(punw_get_proc_name))dlsym(RTLD_DEFAULT, "unw_get_proc_name");
|
|
punw_step = (decltype(punw_step))dlsym(RTLD_DEFAULT, "unw_step");
|
|
punw_init_local = (decltype(punw_init_local))dlsym(RTLD_DEFAULT, "unw_init_local");
|
|
#endif
|
|
#endif
|
|
}
|
|
|
|
int PosixOpen(const char *pathname, int flags, mode_t mode)
|
|
{
|
|
return ::open(pathname, flags, mode);
|
|
}
|
|
|
|
void PosixDoForkHooks()
|
|
{
|
|
Process::PosixForkResetLocks();
|
|
Debug::DeinitSignalHandlers();
|
|
}
|
|
|
|
void PosixShutup()
|
|
{
|
|
int fd = PosixOpen("/dev/null", O_RDWR);
|
|
::dup2(fd, STDERR_FILENO);
|
|
::dup2(fd, STDOUT_FILENO);
|
|
::dup2(fd, STDIN_FILENO);
|
|
::close(fd);
|
|
}
|
|
|
|
void PosixFDYeetus()
|
|
{
|
|
#if defined(AURORA_IS_BSD_DERIVED)
|
|
closefrom(STDERR_FILENO + 1);
|
|
#elif defined(AURORA_IS_LINUX_DERIVED)
|
|
close_range(STDERR_FILENO + 1, UINT_MAX, 0);
|
|
#endif
|
|
}
|
|
|
|
void PosixTerminate()
|
|
{
|
|
::killpg(0, SIGKILL);
|
|
}
|
|
|
|
static bool PosixLseek63(int fd, AuUInt64 offset, int whence, AuUInt64 *pOffset)
|
|
{
|
|
if (offset > std::numeric_limits<off_t>::max())
|
|
{
|
|
SysPushErrorIO("int overflow exploit?");
|
|
return false;
|
|
}
|
|
|
|
#if defined(AURORA_IS_LINUX_DERIVED)
|
|
auto ret = lseek64(fd, offset, whence);
|
|
#elif defined(AURORA_IS_64BIT)
|
|
static_assert(std::numeric_limits<off_t>::max() >= std::numeric_limits<AuInt64>::max(), "unsupported posix os");
|
|
auto ret = lseek(fd, offset, whence);
|
|
#elif defined(AURORA_FORCE_32BIT_FILESYSTEMS_ONLY)
|
|
auto ret = lseek(fd, (off_t)offset, whence);
|
|
#else
|
|
#error ancient 32-bit posix operating systems require 64-bit file awareness
|
|
#endif
|
|
if (ret < 0)
|
|
{
|
|
// Intentionally omitted (thank linuxs' mess of incomplete filesystems)
|
|
// SysPushErrorIO("PosixLseek63 IO Error: {}", ret);
|
|
return false;
|
|
}
|
|
|
|
if (pOffset)
|
|
{
|
|
*pOffset = ret;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
AuUInt64 PosixGetLength(int fd)
|
|
{
|
|
AuUInt64 ret {}, old {};
|
|
bool status {};
|
|
|
|
if (!PosixLseek63(fd, 0, SEEK_CUR, &old))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
status = PosixLseek63(fd, 0, SEEK_END, &ret);
|
|
status &= PosixLseek63(fd, old, SEEK_SET, nullptr);
|
|
return status ? ret : 0;
|
|
}
|
|
|
|
AuUInt64 PosixGetOffset(int fd)
|
|
{
|
|
AuUInt64 ret;
|
|
if (!PosixLseek63(fd, 0, SEEK_CUR, &ret))
|
|
{
|
|
return 0;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
bool PosixSetOffset(int fd, AuUInt64 offset)
|
|
{
|
|
return PosixLseek63(fd, offset, SEEK_SET, nullptr);
|
|
}
|
|
|
|
bool PosixRead(int fd, void *buf, AuUInt32 count, AuUInt32 *pRead)
|
|
{
|
|
AuSInt ret;
|
|
|
|
do
|
|
{
|
|
ret = ::read(fd, buf, count);
|
|
}
|
|
while ((ret == -1 && errno == EINTR));
|
|
|
|
if (ret < 0)
|
|
{
|
|
SysPushErrorIO("PosixRead IO Error: {}", errno);
|
|
return false;
|
|
}
|
|
|
|
if (pRead)
|
|
{
|
|
*pRead = ret;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool PosixWrite(int fd, const void *buf, AuUInt32 count, AuUInt32 *pWritten)
|
|
{
|
|
AuSInt ret;
|
|
|
|
do
|
|
{
|
|
ret = ::write(fd, buf, count);
|
|
}
|
|
while ((ret == -1 && errno == EINTR));
|
|
|
|
if (ret < 0)
|
|
{
|
|
SysPushErrorIO("PosixWrite IO Error: {}", errno);
|
|
return false;
|
|
}
|
|
|
|
if (pWritten)
|
|
{
|
|
*pWritten = ret;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void PosixWriteEoS(int fd)
|
|
{
|
|
::ftruncate(fd, PosixGetOffset(fd));
|
|
}
|
|
|
|
void SysWriteEoS(AuUInt uOSHandle)
|
|
{
|
|
PosixWriteEoS(uOSHandle);
|
|
}
|
|
|
|
void SysCloseHandle(AuUInt uOSHandle)
|
|
{
|
|
::close(uOSHandle);
|
|
}
|
|
|
|
bool SysHandleIsNonZero(AuUInt uOSHandle)
|
|
{
|
|
#if defined(AURORA_IS_64BIT)
|
|
return uOSHandle && (uOSHandle != 0xFFFFFFFFull) && (uOSHandle != 0xFFFFFFFFFFFFFFFFull);
|
|
#else
|
|
return uOSHandle && (uOSHandle != 0xFFFFFFFF);
|
|
#endif
|
|
}
|
|
|
|
void SysFlushHandle(AuUInt uOSHandle)
|
|
{
|
|
::fsync(uOSHandle);
|
|
}
|
|
|
|
int PosixUnlink(const char *pathname)
|
|
{
|
|
return ::unlink(pathname);
|
|
}
|
|
|
|
AuUInt64 SysGetFileLength(AuUInt uOSHandle)
|
|
{
|
|
return PosixGetLength(uOSHandle);
|
|
}
|
|
|
|
void *SysAllocateLarge(AuUInt uLength)
|
|
{
|
|
uLength = AuMemory::RoundPageUp(uLength);
|
|
return ::mmap(0, uLength, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
|
}
|
|
|
|
void SysAllocateFree(void *pBuffer, AuUInt uLength)
|
|
{
|
|
uLength = AuMemory::RoundPageUp(uLength);
|
|
::munmap(pBuffer, uLength);
|
|
}
|
|
|
|
bool SysMemoryLockPages(const void *pVoid, AuUInt uLength)
|
|
{
|
|
return ::mlock(pVoid, uLength) == 0;
|
|
}
|
|
|
|
bool SysMemoryUnlockPages(const void *pVoid, AuUInt uLength)
|
|
{
|
|
return ::munlock(pVoid, uLength) == 0;
|
|
}
|
|
} |