### Build SymCC with CMake and Ninja Source: https://context7.com/eurecom-s3/symcc/llms.txt Instructions to build SymCC, including installing dependencies on Ubuntu, cloning the repository, initializing submodules, and compiling with the QSYM backend. It also includes running tests to verify the installation. ```bash # Install dependencies (Ubuntu) sudo apt install -y git cargo clang-14 cmake g++ git libz3-dev llvm-14-dev llvm-14-tools ninja-build python3-pip zlib1g-dev sudo pip3 install lit # Clone and initialize submodules git clone https://github.com/eurecom-s3/symcc.git cd symcc git submodule update --init --recursive # Build with QSYM backend (recommended for fuzzing) mkdir build && cd build cmake -G Ninja -DSYMCC_RT_BACKEND=qsym .. ninja # Run tests to verify installation ninja check ``` -------------------------------- ### Install Dependencies for SymCC (Ubuntu) Source: https://github.com/eurecom-s3/symcc/blob/master/README.md Installs necessary packages for building and testing SymCC on Ubuntu Groovy, including Git, Cargo, Clang, CMake, G++, Z3, LLVM, Ninja, Python, and Pip. It also installs the 'lit' testing tool. ```bash sudo apt install -y git cargo clang-14 cmake g++ git libz3-dev llvm-14-dev llvm-14-tools ninja-build python3-pip zlib1g-dev && sudo pip3 install lit ``` -------------------------------- ### Build and Run SymCC Docker Container Source: https://github.com/eurecom-s3/symcc/blob/master/README.md Commands to build a local Docker image for SymCC or pull the pre-built image from Docker Hub and start an ephemeral container. ```bash $ docker build -t symcc . $ docker run -it --rm symcc $ docker pull eurecoms3/symcc $ docker run -it --rm symcc ``` -------------------------------- ### CMake Project Setup and LLVM Configuration Source: https://github.com/eurecom-s3/symcc/blob/master/CMakeLists.txt Initializes the CMake project, sets the LLVM version, defines the symbolic runtime backend, and optionally enables 32-bit target support. It finds the LLVM package and checks for version compatibility. ```cmake cmake_minimum_required(VERSION 3.16) project(SymCC) set(LLVM_VERSION "" CACHE STRING "LLVM version to use. The corresponding LLVM dev package must be installed.") set(SYMCC_RT_BACKEND "qsym" CACHE STRING "The symbolic backend to use. Please check symcc-rt to get a list of the available backends.") option(TARGET_32BIT "Make the compiler work correctly with -m32" OFF) # Find LLVM find_package(LLVM ${LLVM_VERSION} REQUIRED CONFIG) message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}") message(STATUS "Using LLVMConfig.cmake from ${LLVM_DIR}") if (${LLVM_VERSION_MAJOR} LESS 8 OR ${LLVM_VERSION_MAJOR} GREATER 17) message(WARNING "The software has been developed for LLVM 8 through 17; \nit is unlikely to work with other versions!") endif() ``` -------------------------------- ### Configure LLVM and Z3 Paths (CMake) Source: https://github.com/eurecom-s3/symcc/blob/master/README.md Provides CMake parameters to specify non-standard installation paths for LLVM and Z3 during the SymCC build process. This is useful when LLVM or Z3 are not installed in default locations or require specific CMake module directories. ```bash -DLLVM_DIR=/path/to/llvm/cmake/module -DZ3_DIR=/path/to/z3/cmake/module ``` -------------------------------- ### C Code Example for SymCC Source: https://github.com/eurecom-s3/symcc/blob/master/README.md A sample C program demonstrating a function `foo` with conditional logic and a `main` function that reads an integer from standard input and passes it to `foo`. This code can be compiled with SymCC to explore symbolic execution paths. ```c #include #include #include int foo(int a, int b) { if (2 * a < b) return a; else if (a % b) return b; else return a + b; } int main(int argc, char* argv[]) { int x; if (read(STDIN_FILENO, &x, sizeof(x)) != sizeof(x)) { printf("Failed to read x\n"); return -1; } printf("%d\n", foo(x, 7)); return 0; } ``` -------------------------------- ### Run SymCC Smoke Tests Source: https://github.com/eurecom-s3/symcc/blob/master/README.md Executes predefined shell scripts to verify the installation and functionality of SymCC for both C and C++ within the Docker environment. ```bash $ ./test/test_sympp_root_in_docker.sh symcc $ ./test/test_readme_c_smoke.sh ``` -------------------------------- ### Configure SymCC Test Backend and LLVM Compatibility Source: https://github.com/eurecom-s3/symcc/blob/master/test/CMakeLists.txt This script sets the FileCheck arguments based on the selected SYMCC_RT_BACKEND. It also ensures compatibility with LLVM version 14 and higher by conditionally adding the --allow-unused-prefixes flag. ```cmake if (SYMCC_RT_BACKEND STREQUAL "qsym") set(SYM_TEST_FILECHECK_ARGS "--check-prefix=QSYM --check-prefix=ANY") elseif (SYMCC_RT_BACKEND STREQUAL "simple") set(SYM_TEST_FILECHECK_ARGS "--check-prefix=SIMPLE --check-prefix=ANY") else() message(FATAL_ERROR "Unknown backend to test: ${SYMCC_RT_BACKEND}") endif() if (${LLVM_VERSION_MAJOR} VERSION_GREATER_EQUAL 14) set(SYM_TEST_FILECHECK_ARGS "${SYM_TEST_FILECHECK_ARGS} --allow-unused-prefixes") endif() ``` -------------------------------- ### Use symcc_make_symbolic for Memory-Based Symbolic Input Source: https://context7.com/eurecom-s3/symcc/llms.txt Illustrates the use of the `symcc_make_symbolic` API to mark specific memory regions as symbolic. This allows for fine-grained control over which data is analyzed symbolically. The example shows compiling the program and running it with memory input mode enabled. ```c // memory_symbolic.c - Using memory-based symbolic input #include #include #include // Declare the SymCC runtime API void symcc_make_symbolic(const void *start, size_t byte_length); #define TARGET_VALUE 0xaaaabbbbccccdddd int main(int argc, char *argv[]) { uint64_t x = 10; uint8_t y = 0; // Mark variables as symbolic symcc_make_symbolic(&x, sizeof(x)); symcc_make_symbolic(&y, sizeof(y)); // SymCC will generate inputs to satisfy these conditions if (x == TARGET_VALUE) { printf("Found target value for x!\n"); } if (y == 42) { printf("Found target value for y!\n"); } return 0; } ``` ```bash # Compile the program ./symcc -O2 memory_symbolic.c -o memory_test # Run with memory input mode enabled export SYMCC_MEMORY_INPUT=1 export SYMCC_OUTPUT_DIR=/tmp/output ./memory_test ``` -------------------------------- ### Define Custom Test Target with Lit Source: https://github.com/eurecom-s3/symcc/blob/master/test/CMakeLists.txt This snippet configures the 'check' custom target using the lit test runner. It includes dependencies on the SymCC runtime and core binaries to ensure the environment is built before testing. ```cmake configure_file("lit.site.cfg.in" "lit.site.cfg") add_custom_target(check lit --verbose --path=${LLVM_TOOLS_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR} COMMENT "Testing the system..." USES_TERMINAL) add_dependencies(check SymCCRuntime SymCC) if (TARGET SymCCRuntime32) add_dependencies(check SymCCRuntime32 SymCC) endif() ``` -------------------------------- ### Compile and Run C Programs with SymCC Source: https://context7.com/eurecom-s3/symcc/llms.txt Demonstrates how to compile a C program using the `symcc` wrapper script, which acts as a drop-in replacement for `clang`. It covers setting the output directory, running the compiled program with symbolic input from stdin, and checking the generated test cases. ```c // test.c - Example program with symbolic execution targets #include #include #include int foo(int a, int b) { if (2 * a < b) return a; else if (a % b) return b; else return a + b; } int main(int argc, char* argv[]) { int x; if (read(STDIN_FILENO, &x, sizeof(x)) != sizeof(x)) { printf("Failed to read x\n"); return -1; } printf("%d\n", foo(x, 7)); return 0; } ``` ```bash # Compile with symbolic execution instrumentation ./symcc test.c -o test # Create output directory for generated test cases mkdir results export SYMCC_OUTPUT_DIR=$(pwd)/results # Run with symbolic input (data from stdin is treated as symbolic) echo 'aaaa' | ./test # Check generated test cases that explore different paths ls -la results/ # Output: 000000, 000001, 000002... # Run again with one of the generated inputs ./test < results/000001 ``` -------------------------------- ### Compile and Execute with SymCC Source: https://github.com/eurecom-s3/symcc/blob/master/README.md Demonstrates compiling a C++ source file using the sym++ compiler wrapper inside the Docker container and executing the resulting binary. ```bash container$ sym++ -o sample sample.cpp container$ echo test | ./sample ``` -------------------------------- ### Compile and Run C++ Programs with SymCC Source: https://context7.com/eurecom-s3/symcc/llms.txt Shows how to compile a C++ program using the `sym++` wrapper script, a drop-in replacement for `clang++`. It explains compiling with the system C++ library and running symbolic execution, including setting the output directory and checking generated test cases. ```cpp // sample.cpp - C++ program with string comparison #include int main(int argc, char *argv[]) { std::cout << "What's your name?" << std::endl; std::string name; std::cin >> name; if (name == "root") std::cout << "What is your command?" << std::endl; else std::cout << "Hello, " << name << "!" << std::endl; return 0; } ``` ```bash # Compile with system C++ library (fast, but loses tracking through std::string) export SYMCC_REGULAR_LIBCXX=yes ./sym++ -o sample sample.cpp # Run symbolic execution mkdir -p /tmp/output export SYMCC_OUTPUT_DIR=/tmp/output echo "test" | ./sample # Check if SymCC found the "root" input cat /tmp/output/000008-optimistic # Output: root ``` -------------------------------- ### Initialize SymCC Submodules Source: https://github.com/eurecom-s3/symcc/blob/master/README.md Updates and initializes the Git submodules for the SymCC project, ensuring all necessary components, like the runtime library, are downloaded. ```bash $ git submodule update --init --recursive ``` -------------------------------- ### Compile C++ with system standard library using SymCC Source: https://github.com/eurecom-s3/symcc/blob/master/docs/C++.txt Demonstrates how to compile a C++ program using the system's uninstrumented standard library. This method is simple but results in the loss of symbolic tracking for data passing through standard library classes. ```bash export SYMCC_REGULAR_LIBCXX=yes sym++ -o myprogram mysource.cpp ./myprogram ``` -------------------------------- ### Build SymCC with CMake and Ninja Source: https://github.com/eurecom-s3/symcc/blob/master/README.md Configures and builds the SymCC project using CMake and Ninja. It specifies the backend (e.g., 'qsym') and the path to the compiler sources. The 'check' target runs the tests. ```bash $ cmake -G Ninja -DSYMCC_RT_BACKEND=qsym /path/to/compiler/sources $ ninja check ``` -------------------------------- ### Compile C++ with instrumented libc++ Source: https://github.com/eurecom-s3/symcc/blob/master/docs/C++.txt Shows how to configure SymCC to use a previously built instrumented libc++ library for compiling C++ projects. ```bash export SYMCC_LIBCXX_PATH=/path-provided-as-cmake-install-prefix-for-libcxx sym++ -o myprogram mysource.cpp ./myprogram ``` -------------------------------- ### Run SymCC Instrumented Program with Symbolic Input Source: https://github.com/eurecom-s3/symcc/blob/master/README.md Executes the compiled program (`./test`) with symbolic input provided via standard input. The program will perform symbolic computations and generate new test cases in the `results` directory. ```bash echo 'aaaa' | ./test ``` -------------------------------- ### Compile C Code with SymCC Source: https://github.com/eurecom-s3/symcc/blob/master/README.md Compiles a C source file (`test.c`) using the `symcc` wrapper script, which integrates symbolic execution capabilities. The output executable is named `test`. ```bash ./symcc test.c -o test ``` -------------------------------- ### Configure SymCC Runtime Environment Variables Source: https://context7.com/eurecom-s3/symcc/llms.txt Lists essential environment variables for controlling SymCC execution, including input/output paths, enabling memory-based input, and configuring backend-specific features like AFL coverage maps. ```bash export SYMCC_OUTPUT_DIR=/path/to/results export SYMCC_INPUT_FILE=/path/to/input.bin export SYMCC_NO_SYMBOLIC_INPUT=1 export SYMCC_MEMORY_INPUT=1 export SYMCC_ENABLE_LINEARIZATION=1 export SYMCC_AFL_COVERAGE_MAP=/path/to/afl_map export SYMCC_LOG_FILE=/tmp/symcc_debug.log ``` -------------------------------- ### Generate Wrapper Scripts Source: https://github.com/eurecom-s3/symcc/blob/master/CMakeLists.txt Uses `configure_file` to generate the `symcc` and `sym++` wrapper scripts from their respective `.in` template files. The `@ONLY` option ensures that only CMake variables are substituted. ```cmake configure_file("compiler/symcc.in" "symcc" @ONLY) configure_file("compiler/sym++.in" "sym++" @ONLY) ``` -------------------------------- ### Execute Hybrid Fuzzing with AFL and SymCC Source: https://context7.com/eurecom-s3/symcc/llms.txt Provides a workflow for combining AFL's mutation-based fuzzing with SymCC's constraint solving. It involves building two versions of the target and using the symcc_fuzzing_helper to synchronize inputs. ```bash cargo install --path util/symcc_fuzzing_helper export AFL_USE_ASAN=1 CC=afl-clang ./configure && make mv target afl_target CC=symcc ./configure && make mv target symcc_target afl-fuzz -M afl-master -i corpus -o afl_out -m none -- ./afl_target @@ afl-fuzz -S afl-secondary -i corpus -o afl_out -m none -- ./afl_target @@ ~/.cargo/bin/symcc_fuzzing_helper -o afl_out -a afl-secondary -n symcc -- ./symcc_target @@ ``` -------------------------------- ### Build instrumented libc++ for SymCC Source: https://github.com/eurecom-s3/symcc/blob/master/docs/C++.txt Provides the commands to build an instrumented version of the LLVM libc++ library. This allows SymCC to track symbolic data through standard library calls. ```bash git clone --depth 1 https://github.com/llvm/llvm-project.git mkdir libcxx_symcc cd libcxx_symcc export SYMCC_REGULAR_LIBCXX=yes export SYMCC_NO_SYMBOLIC_INPUT=yes cmake -G Ninja /path-to-llvm-project/llvm \ -DLLVM_ENABLE_PROJECTS="libcxx;libcxxabi" \ -DLLVM_TARGETS_TO_BUILD="X86" \ -DLLVM_DISTRIBUTION_COMPONENTS="cxx;cxxabi;cxx-headers" \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX=/some/convenient/location \ -DCMAKE_C_COMPILER=/path-to-symcc-with-simple-backend/symcc \ -DCMAKE_CXX_COMPILER=/path-to-symcc-with-simple-backend/sym++ ninja distribution ninja install-distribution unset SYMCC_REGULAR_LIBCXX SYMCC_NO_SYMBOLIC_INPUT ``` -------------------------------- ### Implement Custom Test Case Handler in C Source: https://context7.com/eurecom-s3/symcc/llms.txt Demonstrates how to use symcc_set_test_case_handler to intercept generated test cases programmatically. This allows developers to process symbolic inputs directly in memory rather than writing them to disk. ```c #include #include #include void symcc_make_symbolic(const void *start, size_t byte_length); typedef void (*TestCaseHandler)(const void *, size_t); void symcc_set_test_case_handler(TestCaseHandler handler); #define MAGIC 0xab int found_magic = 0; void handle_test_case(const void *data, size_t data_length) { printf("Generated test case of %zu bytes\n", data_length); if (data_length == 1 && ((const uint8_t *)data)[0] == MAGIC) { found_magic = 1; printf("Found the magic value!\n"); } } int main(int argc, char *argv[]) { symcc_set_test_case_handler(handle_test_case); uint8_t input = 0; symcc_make_symbolic(&input, sizeof(input)); if (input == MAGIC) { printf("Magic input received!\n"); } printf("Magic found: %d\n", found_magic); return 0; } ``` ```bash ./symcc -O2 custom_handler.c -o custom_test export SYMCC_MEMORY_INPUT=1 ./custom_test ``` -------------------------------- ### Find Clang Binary Source: https://github.com/eurecom-s3/symcc/blob/master/CMakeLists.txt Uses `find_program` to locate the `clang` and `clang++` executables. It searches within the `LLVM_TOOLS_BINARY_DIR` and provides documentation strings. If `clang` is not found, it triggers a fatal error. ```cmake find_program(CLANG_BINARY "clang" HINTS ${LLVM_TOOLS_BINARY_DIR} DOC "The clang binary to use in the symcc wrapper script.") find_program(CLANGPP_BINARY "clang++" HINTS ${LLVM_TOOLS_BINARY_DIR} DOC "The clang binary to use in the sym++ wrapper script.") if (NOT CLANG_BINARY) message(FATAL_ERROR "Clang not found; please make sure that the version corresponding to your LLVM installation is available.") endif() ``` -------------------------------- ### Automate Pure Concolic Execution Source: https://context7.com/eurecom-s3/symcc/llms.txt Uses the pure_concolic_execution.sh script to perform iterative symbolic execution. It feeds generated test cases back into the target program until no further paths are discovered. ```bash mkdir corpus echo -n "initial_input" > corpus/seed ./util/pure_concolic_execution.sh -i corpus -o output -f crashes ./instrumented_program ./util/pure_concolic_execution.sh -i corpus -o output ./instrumented_program -r @@ ``` -------------------------------- ### Set SymCC Output Directory Source: https://github.com/eurecom-s3/symcc/blob/master/README.md Configures the environment variable `SYMCC_OUTPUT_DIR` to specify the directory where SymCC will store the results of symbolic execution, including generated test cases. ```bash mkdir results export SYMCC_OUTPUT_DIR=`pwd`/results ``` -------------------------------- ### Add Test Subdirectory Source: https://github.com/eurecom-s3/symcc/blob/master/CMakeLists.txt Includes the `test` subdirectory using `add_subdirectory`. This command processes the `CMakeLists.txt` file in the `test` directory, adding its targets and configurations to the build. ```cmake add_subdirectory(test) ``` -------------------------------- ### External Project for SymCC Runtime Compilation Source: https://github.com/eurecom-s3/symcc/blob/master/CMakeLists.txt Uses CMake's ExternalProject module to build the SymCC runtime as a separate project. This allows for building the runtime with different configurations, such as 32-bit and 64-bit variants, and passes necessary compiler and linker flags. ```cmake # We need to build the runtime as an external project because CMake otherwise # doesn't allow us to build it twice with different options (one 32-bit version # and one 64-bit variant). include(ExternalProject) set(SYM_RUNTIME_BUILD_ARGS -DCMAKE_AR=${CMAKE_AR} -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -DCMAKE_C_FLAGS=${CMAKE_C_FLAGS} -DCMAKE_C_FLAGS_INIT=${CMAKE_C_FLAGS_INIT} -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS} -DCMAKE_CXX_FLAGS_INIT=${CMAKE_CXX_FLAGS_INIT} -DCMAKE_EXE_LINKER_FLAGS=${CMAKE_EXE_LINKER_FLAGS} -DCMAKE_EXE_LINKER_FLAGS_INIT=${CMAKE_EXE_LINKER_FLAGS_INIT} -DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM} -DCMAKE_MODULE_LINKER_FLAGS=${CMAKE_MODULE_LINKER_FLAGS} -DCMAKE_MODULE_LINKER_FLAGS_INIT=${CMAKE_MODULE_LINKER_FLAGS_INIT} -DCMAKE_SHARED_LINKER_FLAGS=${CMAKE_SHARED_LINKER_FLAGS} -DCMAKE_SHARED_LINKER_FLAGS_INIT=${CMAKE_SHARED_LINKER_FLAGS_INIT} -DCMAKE_MODULE_PATH=${CMAKE_MODULE_PATH} -DCMAKE_SYSROOT=${CMAKE_SYSROOT} -DSYMCC_RT_BACKEND=${SYMCC_RT_BACKEND} -DLLVM_VERSION=${LLVM_PACKAGE_VERSION} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DZ3_TRUST_SYSTEM_VERSION=${Z3_TRUST_SYSTEM_VERSION}) ExternalProject_Add(SymCCRuntime SOURCE_DIR ${CMAKE_SOURCE_DIR}/runtime CMAKE_ARGS ${SYM_RUNTIME_BUILD_ARGS} -DCMAKE_EXPORT_COMPILE_COMMANDS=${CMAKE_EXPORT_COMPILE_COMMANDS} -DZ3_DIR=${Z3_DIR} -DLLVM_DIR=${LLVM_DIR} INSTALL_COMMAND "" BUILD_ALWAYS TRUE) ExternalProject_Get_Property(SymCCRuntime BINARY_DIR) set(SYMCC_RUNTIME_DIR ${BINARY_DIR}) ``` -------------------------------- ### LLVM Integration and Compiler Flags Source: https://github.com/eurecom-s3/symcc/blob/master/CMakeLists.txt Re-finds the LLVM package, checks for compatibility with LLVM versions 8 through 18, and sets necessary include directories and definitions. It also configures C++ standard and applies a comprehensive set of compiler warnings and error flags. ```cmake find_package(LLVM REQUIRED CONFIG) message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}") message(STATUS "Using LLVMConfig.cmake from ${LLVM_DIR}") if (${LLVM_VERSION_MAJOR} LESS 8 OR ${LLVM_VERSION_MAJOR} GREATER 18) message(WARNING "The software has been developed for LLVM 8 through 18; \nit is unlikely to work with other versions!") endif() add_definitions(${LLVM_DEFINITIONS}) include_directories(SYSTEM ${LLVM_INCLUDE_DIRS}) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} \n-Wredundant-decls -Wcast-align -Wmissing-include-dirs -Wswitch-default \n-Wextra -Wall -Winvalid-pch -Wredundant-decls -Wformat=2 \n-Wmissing-format-attribute -Wformat-nonliteral -Werror -Wno-error=deprecated-declarations") # Mark nodelete to work around unload bug in upstream LLVM 5.0+ set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,-z,nodelete") # This is the compiler pass that we later load into clang or opt. If LLVM is # built without RTTI we have to disable it for our library too, otherwise we'll ``` -------------------------------- ### Add SymCC Library Source: https://github.com/eurecom-s3/symcc/blob/master/CMakeLists.txt Defines the SymCC library using `add_library` and specifies the source files. It also sets the output name to 'symcc' using `set_target_properties`. ```cmake add_library(SymCC MODULE compiler/Symbolizer.cpp compiler/Pass.cpp compiler/Runtime.cpp compiler/Main.cpp) set_target_properties(SymCC PROPERTIES OUTPUT_NAME "symcc") ``` -------------------------------- ### Conditional 32-bit SymCC Runtime Compilation Source: https://github.com/eurecom-s3/symcc/blob/master/CMakeLists.txt Conditionally compiles a 32-bit version of the SymCC runtime if the TARGET_32BIT option is enabled. This involves passing specific 32-bit flags and paths for LLVM and Z3. ```cmake if (${TARGET_32BIT}) ExternalProject_Add(SymCCRuntime32 SOURCE_DIR ${CMAKE_SOURCE_DIR}/runtime CMAKE_ARGS ${SYM_RUNTIME_BUILD_ARGS} -DCMAKE_C_FLAGS="${CMAKE_C_FLAGS} -m32" -DCMAKE_CXX_FLAGS="${CMAKE_CXX_FLAGS} -m32" -DZ3_DIR=${Z3_32BIT_DIR} -DLLVM_DIR=${LLVM_32BIT_DIR} INSTALL_COMMAND "" BUILD_ALWAYS TRUE) ExternalProject_Get_Property(SymCCRuntime32 BINARY_DIR) set(SYMCC_RUNTIME_32BIT_DIR ${BINARY_DIR}) endif() ``` -------------------------------- ### Configure Clang Load Pass Flag Source: https://github.com/eurecom-s3/symcc/blob/master/CMakeLists.txt Sets the `CLANG_LOAD_PASS` variable based on the LLVM major version. It uses `-Xclang -load -Xclang` for versions less than 13 and `-fpass-plugin=` for version 13 and above. ```cmake if (${LLVM_VERSION_MAJOR} LESS 13) set(CLANG_LOAD_PASS "-Xclang -load -Xclang ") else() set(CLANG_LOAD_PASS "-fpass-plugin=") endif() ``` -------------------------------- ### Conditional Compile Flags Source: https://github.com/eurecom-s3/symcc/blob/master/CMakeLists.txt Conditionally sets the `COMPILE_FLAGS` for the SymCC target. If `LLVM_ENABLE_RTTI` is not enabled, it adds `-fno-rtti` to the compile flags. ```cmake if (NOT LLVM_ENABLE_RTTI) set_target_properties(SymCC PROPERTIES COMPILE_FLAGS "-fno-rtti") endif() ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.