Skip to content

Commit

Permalink
Library Forwarding: Allow reading standard library headers from a dev…
Browse files Browse the repository at this point in the history
…elopment x86 rootfs
  • Loading branch information
neobrain authored and asahilina committed Dec 20, 2024
1 parent 7e257cc commit eef7657
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 22 deletions.
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

0 comments on commit eef7657

Please sign in to comment.