From d8edbba71c80840ec9103ee0b0f7d6b1f4bb6ff2 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Thu, 30 Sep 2021 18:15:41 -0700 Subject: [PATCH] Thunks: Minor fixes to the config and loading There was a hard upper limit to 128 json elements, this has now been removed. The debugging text for the thunk overlay is now disabled. It can get very spammy but it is useful for debugging purposes. Fixes an issue where thunks would be entirely disabled if a RootFS isn't set. This meant debugging in a chroot or x86_64 host was breaking rootfs --- Source/Tests/LinuxSyscalls/FileManagement.cpp | 56 +++++++++++++++---- 1 file changed, 46 insertions(+), 10 deletions(-) diff --git a/Source/Tests/LinuxSyscalls/FileManagement.cpp b/Source/Tests/LinuxSyscalls/FileManagement.cpp index 5538418c1..be2ee9226 100644 --- a/Source/Tests/LinuxSyscalls/FileManagement.cpp +++ b/Source/Tests/LinuxSyscalls/FileManagement.cpp @@ -29,6 +29,24 @@ $end_info$ #include +namespace JSON { + struct JsonAllocator { + jsonPool_t PoolObject; + std::unique_ptr> json_objects; + }; + static_assert(offsetof(JsonAllocator, PoolObject) == 0, "This needs to be at offset zero"); + + json_t* PoolInit(jsonPool_t* Pool) { + JsonAllocator* alloc = reinterpret_cast(Pool); + alloc->json_objects = std::make_unique>(); + return &*alloc->json_objects->emplace(alloc->json_objects->end()); + } + + json_t* PoolAlloc(jsonPool_t* Pool) { + JsonAllocator* alloc = reinterpret_cast(Pool); + return &*alloc->json_objects->emplace(alloc->json_objects->end()); + } +} namespace FEXCore::Context { struct Context; @@ -75,7 +93,7 @@ static bool LoadFile(std::vector &Data, const std::string &Filename) { FileManager::FileManager(FEXCore::Context::Context *ctx) : EmuFD {ctx} { - + auto ThunkConfigFile = ThunkConfig(); if (ThunkConfigFile.size()) { @@ -86,8 +104,14 @@ FileManager::FileManager(FEXCore::Context::Context *ctx) if (LoadFile(FileData, ThunkConfigFile)) { FileData.push_back(0); - json_t mem[128]; - json_t const* json = json_create( &FileData.at(0), mem, sizeof mem / sizeof *mem ); + JSON::JsonAllocator Pool { + .PoolObject = { + .init = JSON::PoolInit, + .alloc = JSON::PoolAlloc, + }, + }; + + json_t const *json = json_createWithPool(&FileData.at(0), &Pool.PoolObject); json_t const* thunks = json_getProperty( json, "thunks" ); if ( !thunks || JSON_OBJ != json_getType( thunks ) ) { @@ -101,23 +125,32 @@ FileManager::FileManager(FEXCore::Context::Context *ctx) if (propertyType == JSON_TEXT) { char const* RootFSLib = json_getValue( thunk ); - ThunkOverlays.emplace(RootFSLib, ThunkGuestPath / GuestThunk); + auto ThunkPath = ThunkGuestPath / GuestThunk; + if (std::filesystem::exists(ThunkPath)) { + ThunkOverlays.emplace(RootFSLib, ThunkPath); + } } else if (propertyType == JSON_ARRAY) { json_t const* child; for( child = json_getChild( thunk ); child != 0; child = json_getSibling( child ) ) { if (json_getType( child ) == JSON_TEXT) { char const* RootFSLib = json_getValue( child ); - ThunkOverlays.emplace(RootFSLib, ThunkGuestPath / GuestThunk); + auto ThunkPath = ThunkGuestPath / GuestThunk; + if (std::filesystem::exists(ThunkPath)) { + ThunkOverlays.emplace(RootFSLib, ThunkPath); + } } } } } } - if (ThunkOverlays.size()) { - LogMan::Msg::I("Thunk Overlays:"); - for (auto &Thunk: ThunkOverlays) { - LogMan::Msg::I("\t%s -> %s", Thunk.first.c_str(), Thunk.second.c_str()); + if (false) { + // Useful for debugging + if (ThunkOverlays.size()) { + LogMan::Msg::I("Thunk Overlays:"); + for (auto &Thunk: ThunkOverlays) { + LogMan::Msg::I("\t%s -> %s", Thunk.first.c_str(), Thunk.second.c_str()); + } } } } @@ -132,7 +165,6 @@ std::string FileManager::GetEmulatedPath(const char *pathname, bool FollowSymlin auto RootFSPath = LDPath(); if (!pathname || // If no pathname pathname[0] != '/' || // If relative - RootFSPath.empty() || // If RootFS doesn't exist strcmp(pathname, "/") == 0) { // If we are getting root return {}; } @@ -142,6 +174,10 @@ std::string FileManager::GetEmulatedPath(const char *pathname, bool FollowSymlin return thunkOverlay->second; } + if (RootFSPath.empty()) { // If RootFS doesn't exist + return {}; + } + std::string Path = RootFSPath + pathname; if (FollowSymlink) { std::error_code ec;