Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
67 changes: 47 additions & 20 deletions ThunkLibs/Generator/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "llvm/Support/Signals.h"

#include <iostream>
#include <optional>
#include <string>

#include "interface.h"
Expand All @@ -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;
}
Expand All @@ -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;
}
Expand All @@ -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") {
Expand All @@ -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());
}
6 changes: 5 additions & 1 deletion ThunkLibs/GuestLibs/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion ThunkLibs/HostLibs/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading