diff --git a/CMakeLists.txt b/CMakeLists.txt index febba44798..aefb427121 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,6 +37,7 @@ option(USE_PDB_DEBUGINFO "Builds debug info in PDB format" FALSE) set (X86_32_TOOLCHAIN_FILE "${CMAKE_CURRENT_SOURCE_DIR}/toolchain_x86_32.cmake" CACHE FILEPATH "Toolchain file for the (cross-)compiler targeting i686") set (X86_64_TOOLCHAIN_FILE "${CMAKE_CURRENT_SOURCE_DIR}/toolchain_x86_64.cmake" CACHE FILEPATH "Toolchain file for the (cross-)compiler targeting x86_64") +set (X86_DEV_ROOTFS "/" CACHE FILEPATH "Toolchain file for the (cross-)compiler targeting x86_64") set (DATA_DIRECTORY "${CMAKE_INSTALL_PREFIX}/share/fex-emu" CACHE PATH "global data directory") string(FIND ${CMAKE_BASE_NAME} mingw CONTAINS_MINGW) @@ -479,6 +480,7 @@ if (BUILD_THUNKS) "-DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}" "-DFEX_PROJECT_SOURCE_DIR=${FEX_PROJECT_SOURCE_DIR}" "-DGENERATOR_EXE=$" + "-DX86_DEV_ROOTFS=${X86_DEV_ROOTFS}" INSTALL_COMMAND "" BUILD_ALWAYS ON DEPENDS thunkgen @@ -497,6 +499,7 @@ if (BUILD_THUNKS) "-DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}" "-DFEX_PROJECT_SOURCE_DIR=${FEX_PROJECT_SOURCE_DIR}" "-DGENERATOR_EXE=$" + "-DX86_DEV_ROOTFS=${X86_DEV_ROOTFS}" INSTALL_COMMAND "" BUILD_ALWAYS ON DEPENDS thunkgen diff --git a/ThunkLibs/Generator/main.cpp b/ThunkLibs/Generator/main.cpp index a378cc0902..4a504405ad 100644 --- a/ThunkLibs/Generator/main.cpp +++ b/ThunkLibs/Generator/main.cpp @@ -4,6 +4,7 @@ #include "llvm/Support/Signals.h" #include +#include #include #include "interface.h" @@ -17,7 +18,7 @@ void print_usage(const char* program_name) { int main(int argc, char* const argv[]) { llvm::sys::PrintStackTraceOnErrorSignal(argv[0]); - if (argc < 5) { + if (argc < 6) { print_usage(argv[0]); return EXIT_FAILURE; } @@ -32,7 +33,7 @@ int main(int argc, char* const argv[]) { } // Process arguments before the "--" separator - if (argc != 5 && argc != 6) { + if (argc != 6 && argc != 7) { print_usage(argv[0]); return EXIT_FAILURE; } @@ -42,6 +43,7 @@ int main(int argc, char* const argv[]) { const std::string libname = *arg++; const std::string target_abi = *arg++; const std::string output_filename = *arg++; + const std::string x86_rootfs = *arg++; OutputFilenames output_filenames; if (target_abi == "-host") { @@ -65,27 +67,52 @@ int main(int argc, char* const argv[]) { ClangTool GuestTool = Tool; - { - const bool is_32bit_guest = (argv[5] == std::string_view {"-for-32bit-guest"}); - auto append_guest_args = [is_32bit_guest](const clang::tooling::CommandLineArguments& Args, clang::StringRef) { - clang::tooling::CommandLineArguments AdjustedArgs = Args; - const char* platform = is_32bit_guest ? "i686" : "x86_64"; - if (is_32bit_guest) { - AdjustedArgs.push_back("-m32"); - AdjustedArgs.push_back("-DIS_32BIT_THUNK"); - } - AdjustedArgs.push_back(std::string {"--target="} + platform + "-linux-unknown"); - AdjustedArgs.push_back("-isystem"); - AdjustedArgs.push_back(std::string {"/usr/"} + platform + "-linux-gnu/include/"); - AdjustedArgs.push_back("-DGUEST_THUNK_LIBRARY"); - return AdjustedArgs; - }; - GuestTool.appendArgumentsAdjuster(append_guest_args); - } - + auto append_x86_rootfs_includes = [&x86_rootfs](clang::tooling::CommandLineArguments& Args, const char* triple) { + if (x86_rootfs == "/") { + return; + } + + Args.push_back("--sysroot"); + Args.push_back(x86_rootfs); + + // The dev rootfs is only really needed for the standard library. + // Other libraries generally don't have platform specific headers. + Args.push_back("-idirafter"); + Args.push_back("/usr/include/"); + }; + + // Analyse data layout for guest ABI + const bool is_32bit_guest = (argv[6] == std::string_view {"-for-32bit-guest"}); + GuestTool.appendArgumentsAdjuster([&](const clang::tooling::CommandLineArguments& Args, clang::StringRef) { + clang::tooling::CommandLineArguments AdjustedArgs = Args; + const char* platform = is_32bit_guest ? "i686-linux-gnu" : "x86_64-linux-gnu"; + if (is_32bit_guest) { + AdjustedArgs.push_back("-m32"); + AdjustedArgs.push_back("-DIS_32BIT_THUNK"); + } + AdjustedArgs.push_back("-DGUEST_THUNK_LIBRARY"); + AdjustedArgs.push_back(std::string {"--target="} + platform); + AdjustedArgs.push_back("-isystem"); + AdjustedArgs.push_back(std::string {"/usr/"} + platform + "/include/"); + + append_x86_rootfs_includes(AdjustedArgs, platform); + + return AdjustedArgs; + }); auto data_layout_analysis_factory = std::make_unique(); GuestTool.run(data_layout_analysis_factory.get()); auto& data_layout = data_layout_analysis_factory->GetDataLayout(); + // Run generator for target ABI + Tool.appendArgumentsAdjuster([&](const clang::tooling::CommandLineArguments& Args, clang::StringRef) { + clang::tooling::CommandLineArguments AdjustedArgs = Args; + AdjustedArgs.push_back("-DIS_HOST_THUNKGEN_PASS"); + if (target_abi == "-guest") { + const char* platform = is_32bit_guest ? "i686-linux-gnu" : "x86_64-linux-gnu"; + append_x86_rootfs_includes(AdjustedArgs, platform); + } + + return AdjustedArgs; + }); return Tool.run(std::make_unique(std::move(libname), std::move(output_filenames), data_layout).get()); } diff --git a/ThunkLibs/GuestLibs/CMakeLists.txt b/ThunkLibs/GuestLibs/CMakeLists.txt index cff9943e9a..4482588597 100644 --- a/ThunkLibs/GuestLibs/CMakeLists.txt +++ b/ThunkLibs/GuestLibs/CMakeLists.txt @@ -9,6 +9,10 @@ if (ENABLE_CLANG_THUNKS) add_link_options(${LD_OVERRIDE}) endif() +if (NOT X86_DEV_ROOTFS) + message(FATAL_ERROR "X86_DEV_ROOTFS must be set (use \"/\" to ignore)") +endif() + find_program(CCACHE_PROGRAM ccache) if(CCACHE_PROGRAM) message(STATUS "CCache enabled for guest thunks") @@ -77,7 +81,7 @@ function(generate NAME SOURCE_FILE) OUTPUT "${OUTFILE}" DEPENDS "${GENERATOR_EXE}" DEPENDS "${SOURCE_FILE}" - COMMAND "${GENERATOR_EXE}" "${SOURCE_FILE}" "${NAME}" "-guest" "${OUTFILE}" ${BITNESS_FLAGS} -- -std=c++20 ${BITNESS_FLAGS2} + COMMAND "${GENERATOR_EXE}" "${SOURCE_FILE}" "${NAME}" "-guest" "${OUTFILE}" "${X86_DEV_ROOTFS}" ${BITNESS_FLAGS} -- -std=c++20 ${BITNESS_FLAGS2} # Expand compile definitions to space-separated list of -D parameters "$<$:;-D$>" # Expand include directories to space-separated list of -isystem parameters diff --git a/ThunkLibs/HostLibs/CMakeLists.txt b/ThunkLibs/HostLibs/CMakeLists.txt index 8d8d6b2b24..cec5b81001 100644 --- a/ThunkLibs/HostLibs/CMakeLists.txt +++ b/ThunkLibs/HostLibs/CMakeLists.txt @@ -53,7 +53,7 @@ function(generate NAME SOURCE_FILE GUEST_BITNESS) OUTPUT "${OUTFILE}" DEPENDS "${SOURCE_FILE}" DEPENDS thunkgen - COMMAND thunkgen "${SOURCE_FILE}" "${NAME}" "-host" "${OUTFILE}" ${BITNESS_FLAGS} -- -std=c++20 + COMMAND thunkgen "${SOURCE_FILE}" "${NAME}" "-host" "${OUTFILE}" "${X86_DEV_ROOTFS}" ${BITNESS_FLAGS} -- -std=c++20 # Expand compile definitions to space-separated list of -D parameters "$<$:;-D$>" # Expand include directories to space-separated list of -isystem parameters