Library Forwarding: Allow reading standard library headers from a development x86 rootfs

This commit is contained in:
Tony Wasserka authored and Asahi Lina committed 2024-12-24 19:41:29 +09:00
1 parent cd6722f77b
commit d503366816
4 files changed
+55 -21

No files matched your search

+3
View File
@@ -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 "Path to the sysroot used for cross-compiling for i686 and 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=$<TARGET_FILE:thunkgen>"
"-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=$<TARGET_FILE:thunkgen>"
"-DX86_DEV_ROOTFS=${X86_DEV_ROOTFS}"
INSTALL_COMMAND ""
BUILD_ALWAYS ON
DEPENDS thunkgen
+46 -19
View File
@@ -4,6 +4,7 @@
#include "llvm/Support/Signals.h"
#include <iostream>
#include <optional>
#include <string>
#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<AnalyzeDataLayoutActionFactory>();
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<GenerateThunkLibsActionFactory>(std::move(libname), std::move(output_filenames), data_layout).get());
}
+5 -1
View File
@@ -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
"$<$<BOOL:${compile_prop}>:;-D$<JOIN:${compile_prop},;-D>>"
# Expand include directories to space-separated list of -isystem parameters
+1 -1
View File
@@ -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
"$<$<BOOL:${compile_prop}>:;-D$<JOIN:${compile_prop},;-D>>"
# Expand include directories to space-separated list of -isystem parameters