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
This commit is contained in:
Ryan Houdek committed 2021-03-21 01:11:47 -07:00
1 parent 8c1f2eb0b3
commit 5b8bf8dd24
1 file changed
+15 -1
+15 -1
View File
@@ -3,6 +3,7 @@
#include <FEXCore/Utils/LogManager.h>
#include <cstring>
#include <elf.h>
#include <filesystem>
#include <fstream>
#include <stdint.h>
#include <vector>
@@ -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)) {