From 5b8bf8dd2422f4fbed86d82057ecb19085b58d64 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Sun, 21 Mar 2021 00:28:44 -0700 Subject: [PATCH] Adds some additional logic for finding absolute soft linked linker Ubuntu's x86_64 rootfs does a soft link from `/lib64/ld-linux-x86-64.so.2` to an absolute path of `/lib/x86_64-linux-gnu/ld-2.32.so` Our frontend ELF loader logic would resolve this symlink to be just `/lib/x86_64-linux-gnu/ld-2.32.so` which would then fail. Adds some additional logic to our frontend that if the symlink ends up being a softlink to an absolute address then it'll first resolve that symlink. Then combines rootfs + absolute path. If that still fails then it'll fall down the regular linker path, which could still find the linker on the host side. This is all a bit of a kludge to just work around Ubuntu doing an absolute address rather than a relative one. Fixes #869 --- External/FEXCore/Source/Utils/ELFLoader.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/External/FEXCore/Source/Utils/ELFLoader.cpp b/External/FEXCore/Source/Utils/ELFLoader.cpp index 64dd5327f..ef3dbc395 100644 --- a/External/FEXCore/Source/Utils/ELFLoader.cpp +++ b/External/FEXCore/Source/Utils/ELFLoader.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -85,7 +86,20 @@ ELFContainer::ELFContainer(std::string const &Filename, std::string const &RootF else { RawString = &RawFile.at(InterpreterHeader._64->p_offset); } - if (!RootFS.empty() && LoadELF(RootFS + RawString)) { + std::string RootFSLink = RootFS + RawString; + while (std::filesystem::is_symlink(RootFSLink)) { + // Do some special handling if the RootFS's linker is a symlink + // Ubuntu's rootFS by default provides an absolute location symlink to the linker + // Resolve this around back to the rootfs + auto SymlinkTarget = std::filesystem::read_symlink(RootFSLink); + if (SymlinkTarget.is_absolute()) { + RootFSLink = RootFS + SymlinkTarget.string(); + } + else { + break; + } + } + if (LoadELF(RootFSLink)) { // Found the interpreter in the rootfs } else if (!LoadELF(RawString)) {