[*] Linux alternative dynamic loader: AuProcess main process path has to be pulled from the procmap instead of arg[0]

This commit is contained in:
Reece Wilson 2024-06-29 16:06:42 +01:00
parent 05737d61fe
commit a1672a33d7
4 changed files with 60 additions and 19 deletions

View File

@ -79,6 +79,7 @@ static void Init()
AuProcess::WarmStartupCaches();
Aurora::Threading::InitSleep();
Aurora::CmdLine::Init();
Aurora::Process::InitProcess();
Aurora::SWInfo::InitSwInfo();
@ -99,7 +100,6 @@ static void Init()
Aurora::Telemetry::Init();
Aurora::Debug::InitDebug();
Aurora::Locale::Init();
Aurora::CmdLine::Init();
Aurora::Processes::Init();
Aurora::Hashing::InitHashing();
Aurora::Async::InitAsync();

View File

@ -32,6 +32,8 @@ namespace Aurora::CmdLine
}
#if defined(AURORA_IS_POSIX_DERIVED)
AuString gHackLoader;
static AuList<AuString> GetProcFSCmdString()
{
AuList<AuString> args;
@ -67,6 +69,7 @@ namespace Aurora::CmdLine
{
if (AuStringContains(args[0], "ld-Aurora"))
{
gHackLoader = args[0];
args.erase(args.begin());
}
}

View File

@ -18,6 +18,21 @@
namespace Aurora::Process
{
static AuString gCachedModule, gCachedPartialPath, gCachedFullPath;
static AuInitOnce gInitOnce;
void ForceReplacePathHack(const AuString &path)
{
static AuInitOnce gInitOnce2;
gInitOnce2.Call([&]()
{
AuResetMember(gCachedModule);
AuResetMember(gCachedPartialPath);
AuResetMember(gCachedFullPath, path);
AuResetMember(gInitOnce);
});
}
AUKN_SYM bool GetWorkingDirectory(AuString &path)
{
#if !defined(AURORA_IS_MODERNNT_DERIVED)
@ -188,9 +203,6 @@ namespace Aurora::Process
static bool GetModulePath(const AuString *&module, const AuString *&partialPath, const AuString *&fullPath)
{
static AuString cachedModule, cachedPartialPath, cachedFullPath;
static AuInitOnce gInitOnce;
if (!AuThreading::InitOnceLocker::TryLock(&gInitOnce, true))
{
gInitOnce.Wait();
@ -203,17 +215,18 @@ namespace Aurora::Process
{
char spitter;
if (GetModulePathSlow(cachedFullPath, spitter))
if (gCachedFullPath.size() ||
GetModulePathSlow(gCachedFullPath, spitter))
{
auto indexA = cachedFullPath.find_last_of(spitter);
auto indexA = gCachedFullPath.find_last_of(spitter);
if (indexA != AuString::npos)
{
cachedModule = cachedFullPath.substr(indexA + 1);
cachedPartialPath = cachedFullPath.substr(0, indexA);
gCachedModule = gCachedFullPath.substr(indexA + 1);
gCachedPartialPath = gCachedFullPath.substr(0, indexA);
if (!cachedPartialPath.ends_with(AuFS::kPathSplitter))
if (!gCachedPartialPath.ends_with(AuFS::kPathSplitter))
{
cachedPartialPath += AuFS::kPathSplitter;
gCachedPartialPath += AuFS::kPathSplitter;
}
}
else
@ -240,9 +253,9 @@ namespace Aurora::Process
return false;
}
module = &cachedModule;
fullPath = &cachedFullPath;
partialPath = &cachedPartialPath;
module = &gCachedModule;
fullPath = &gCachedFullPath;
partialPath = &gCachedPartialPath;
return true;
}

View File

@ -18,8 +18,15 @@
using Elf_Shdr = Elf32_Shdr;
#endif
namespace Aurora::CmdLine
{
extern AuString gHackLoader;
}
namespace Aurora::Process
{
void ForceReplacePathHack(const AuString &path);
void InitProcessMapLinux()
{
@ -44,11 +51,14 @@ namespace Aurora::Process
fileName = *optProcessPath;
}
}
else
{
if (!AuIOFS::FileExists(fileName))
{
// NO FILE linux-vdso.so.1
return 0;
}
}
AuList<AuTuple<AuUInt, AuUInt, AuUInt, AuUInt>> sections;
for (int j = 0; j < info->dlpi_phnum; j++)
@ -124,16 +134,32 @@ namespace Aurora::Process
name = kSectionNameFile;
}
AuOptional<const AuString &> optProcessPath;
if (AuCmdLine::gHackLoader.size())
{
optProcessPath = GetProcessFullPath();
}
if (name.size())
{
bIsSpecialFile = AuIOFS::FileExists(name);
if (bIsSpecialFile)
{
for (const auto &[uBaseAddress, pathSectionPair] : gModuleMap)
for (auto &[uBaseAddress, pathSectionPair] : gModuleMap)
{
if (uBaseAddress == base)
{
if (optProcessPath)
{
if (AuGet<0>(pathSectionPair) == optProcessPath.Value())
{
ForceReplacePathHack(name);
AuGet<0>(pathSectionPair) = name;
AuResetMember(optProcessPath);
}
}
return;
}
@ -268,8 +294,7 @@ namespace Aurora::Process
object->SetOffset(strtab.sh_offset);
if (!object->Read(AuMemoryViewStreamWrite(AuMemoryViewWrite(strHeap.data(),
strHeap.size()
),
strHeap.size()),
read)))
{
SysPushErrorIO();