From 5af4c68b7530f5712264df224526c0e666a5aa57 Mon Sep 17 00:00:00 2001 From: Romain Malmain Date: Thu, 4 Apr 2024 20:02:52 +0200 Subject: [PATCH] SymCC Runtime Integration * Removed options to located symcc. * Automatic building of symcc-rt. * Clean integration with meson using dependencies. * Option to change symcc rt backend. * Option to compile symcc rt statically and dynamically. --- README.md | 42 ++++++++++------------------------- configure | 21 ------------------ meson.build | 38 ++++++++++++++++++++++++++----- meson_options.txt | 6 +++++ scripts/meson-buildoptions.sh | 7 ++++++ 5 files changed, 57 insertions(+), 57 deletions(-) diff --git a/README.md b/README.md index 2e49ef53c6..c0413c5caf 100644 --- a/README.md +++ b/README.md @@ -8,28 +8,16 @@ changes to happen there, but PR may be accepted. ## How to build -SymQEMU requires [SymCC](https://github.com/eurecom-s3/symcc), so please -download and build SymCC first. For best results, configure it with the QSYM -backend as explained in the README. For the impatient, here's a quick summary of -the required steps that may or may not work on your system: - +First of all, make sure the [symcc-rt](https://github.com/eurecom-s3/symcc-rt.git) submodule is initialized: ``` shell -$ git clone https://github.com/eurecom-s3/symcc.git -$ cd symcc -$ git submodule update --init -$ mkdir build -$ cd build -$ cmake -G Ninja -DQSYM_BACKEND=ON .. -$ ninja +$ git submodule update --init --recursive subprojects/symcc-rt ``` -Next, make sure that QEMU's build dependencies are installed. Most package +Make sure that QEMU's build dependencies are installed. Most package managers provide a command to get them, e.g., `apt build-dep qemu` on Debian and Ubuntu, or `dnf builddep qemu` on Fedora and CentOS. -We've extended QEMU's configuration script to accept pointers to SymCC's source -and binaries. The following invocation is known to work on Debian 10, Arch and -Fedora 33: +The following invocation is known to work on Debian 10, Arch and Fedora 33: ``` shell $ mkdir build @@ -42,9 +30,7 @@ $ ../configure \ --disable-opengl \ --disable-virglrenderer \ --disable-werror \ - --target-list=x86_64-linux-user \ - --symcc-source=../symcc \ - --symcc-build=../symcc/build + --target-list=x86_64-linux-user $ make -j ``` @@ -54,6 +40,12 @@ target architectures is possible in principle but will require a bit of work because the current implementation assumes that we can pass around host pointers in guest registers. +## SymQEMU compilation options + +Several compilation options are available: +- `enable-symcc-shared`: Compile SymQEMU with the shared library of `SymCC Runtime` instead of a static library +- `symcc-backend`: Choose a specific backend from `SymCC Runtime`. Please have a look to [symcc-rt](https://github.com/eurecom-s3/symcc-rt.git) to get an exhaustive list of available backends. + ## Running SymQEMU If you built SymQEMU as described above, the binary will be in @@ -90,17 +82,7 @@ you'll have to run AFL in QEMU mode by adding `-Q` to its command line; the fuzzing helper will automatically pick up the setting and use QEMU mode too.) ## Build with Docker -First, make sure to have an up-to-date Docker image of SymCC. If you -don't have one, either in the submodule, run: - -``` shell -git submodule update --init --recursive symcc -cd symcc -docker build -t symcc . -cd .. -``` - -Then build the SymQEMU image with (this will also run the tests): +Build the SymQEMU image with (this will also run the tests): ```shell docker build -t symqemu . ``` diff --git a/configure b/configure index 58b500a405..d7e0926ff1 100755 --- a/configure +++ b/configure @@ -242,8 +242,6 @@ default_cflags='-O2 -g' git_submodules_action="update" docs="auto" EXESUF="" -symcc_source="" -symcc_build="" system="yes" linux_user="" bsd_user="" @@ -696,10 +694,6 @@ for opt do ;; --static) static="yes" ;; - --symcc-source=*) symcc_source="$optarg" - ;; - --symcc-build=*) symcc_build="$optarg" - ;; --host=*|--build=*|\ --disable-dependency-tracking|\ --sbindir=*|--sharedstatedir=*|\ @@ -880,8 +874,6 @@ Advanced options (experts only): start the emulator (only use if you are including desired devices in configs/devices/) --with-devices-ARCH=NAME override default configs/devices - --symcc-source=PATH PATH to SymCC source code - --symcc-build=PATH PATH to the build directory of SymCC with Qsym backend --enable-debug enable common debug build options --cpu=CPU Build for host CPU [$cpu] --disable-containers don't use containers for cross-building @@ -1678,19 +1670,6 @@ if test "$targetos" = windows; then echo "CONFIG_WIN32=y" >> contrib/plugins/$config_host_mak fi -echo "# SymQEMU config" >> $config_host_mak -if test -e "$symcc_source/runtime/RuntimeCommon.h"; then - echo "SYMCC_INC=$symcc_source/runtime" >> $config_host_mak -else - error_exit "SymCC (source)" "Point --symcc-source to the SymCC source code" -fi -if test -e "$symcc_build/SymRuntime-prefix/src/SymRuntime-build/libSymRuntime.so"; then - echo "SYMCC_BUILD=$symcc_build/SymRuntime-prefix/src/SymRuntime-build" >> $config_host_mak - echo "SYMCC_LIBS=$symcc_build/SymRuntime-prefix/src/SymRuntime-build/libSymRuntime.so" >> $config_host_mak -else - error_exit "SymCC (runtime)" "Point --symcc-build to the SymCC build directory" -fi - # tests/tcg configuration (config_host_mak=tests/tcg/config-host.mak mkdir -p tests/tcg diff --git a/meson.build b/meson.build index 6a3ee8c9fa..300331dc80 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('qemu', ['c'], meson_version: '>=0.63.0', - default_options: ['warning_level=1', 'c_std=gnu11', 'cpp_std=gnu++11', 'b_colorout=auto', + default_options: ['warning_level=1', 'c_std=gnu11', 'cpp_std=gnu++17', 'b_colorout=auto', 'b_staticpic=false', 'stdsplit=false', 'optimization=2', 'b_pie=true'], version: files('VERSION')) @@ -13,6 +13,7 @@ not_found = dependency('', required: false) keyval = import('keyval') ss = import('sourceset') fs = import('fs') +cmake = import('cmake') targetos = host_machine.system() sh = find_program('sh') @@ -1080,6 +1081,26 @@ if targetos == 'linux' and (have_system or have_tools) required: get_option('libudev')) endif +symcc_backend = get_option('symcc_backend') + +if not fs.is_file('subprojects/symcc-rt/RuntimeCommon.h') + error_msg='''The SymCC source path "@0@" is incorrect. +Did you initialize symcc-rt subrepository? (git submodule update --init --recursive subprojects/symcc-rt)'''.format('subprojects/symcc') + error(error_msg) +endif + +symcc_rt = not_found + +symcc_var = cmake.subproject_options() +symcc_var.add_cmake_defines({ 'SYMCC_RT_BACKEND': symcc_backend }) + +symcc_rt_proj = cmake.subproject('symcc-rt', options: symcc_var) +if get_option('symcc_shared') + symcc_rt = symcc_rt_proj.dependency('SymccRtShared') +else + symcc_rt = symcc_rt_proj.dependency('SymccRtStatic') +endif + mpathlibs = [libudev] mpathpersist = not_found if targetos == 'linux' and have_tools and get_option('mpath').allowed() @@ -3508,7 +3529,6 @@ subdir('plugins') subdir('ebpf') common_user_inc = [] -common_user_inc += config_host['SYMCC_INC'].split() subdir('common-user') subdir('bsd-user') @@ -3738,6 +3758,9 @@ common_ss.add(qom, qemuutil) common_ss.add_all(when: 'CONFIG_SYSTEM_ONLY', if_true: [system_ss]) common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss) +common_ss.add(symcc_rt) +specific_ss.add(symcc_rt) + common_all = common_ss.apply(config_all, strict: false) common_all = static_library('common', build_by_default: false, @@ -3885,16 +3908,13 @@ foreach target : target_dirs exe_name += '-unsigned' endif - symcc_libs = files(config_host['SYMCC_LIBS'].split()) - emulator = executable(exe_name, exe['sources'], install: true, c_args: c_args, dependencies: arch_deps + deps + exe['dependencies'], - objects: [lib.extract_all_objects(recursive: true), symcc_libs], + objects: lib.extract_all_objects(recursive: true), link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []), link_args: link_args, - build_rpath: config_host['SYMCC_BUILD'], win_subsystem: exe['win_subsystem']) if targetos == 'darwin' @@ -4341,6 +4361,12 @@ summary_info += {'netmap support': have_netmap} summary_info += {'l2tpv3 support': have_l2tpv3} summary(summary_info, bool_yn: true, section: 'Network backends') +# SymQEMU +summary_info = {} +summary_info += {'SymCC Backend': symcc_backend} +summary_info += {'SymCC Shared Library': get_option('symcc_shared')} +summary(summary_info, bool_yn: true, section: 'SymQEMU') + # Libraries summary_info = {} summary_info += {'libtasn1': tasn1} diff --git a/meson_options.txt b/meson_options.txt index c9baeda639..5a33a3d934 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -368,3 +368,9 @@ option('qemu_ga_version', type: 'string', value: '', option('hexagon_idef_parser', type : 'boolean', value : true, description: 'use idef-parser to automatically generate TCG code for the Hexagon frontend') + +# SymQEMU related options +option('symcc_backend', type: 'string', value: 'qsym', + description: 'SymCC backend to use. Please check SymCC Runtime for a list of available backends.') +option('symcc_shared', type: 'boolean', value: false, + description: 'Compile SymCC Runtime dynamically instead of statically.') diff --git a/scripts/meson-buildoptions.sh b/scripts/meson-buildoptions.sh index 680fa3f581..6fa0bcc330 100644 --- a/scripts/meson-buildoptions.sh +++ b/scripts/meson-buildoptions.sh @@ -47,6 +47,8 @@ meson_options_help() { printf "%s\n" ' clang/llvm and coroutine backend ucontext)' printf "%s\n" ' --enable-sanitizers enable default sanitizers' printf "%s\n" ' --enable-strip Strip targets on install' + printf "%s\n" ' --enable-symcc-shared Compile SymCC Runtime dynamically instead of' + printf "%s\n" ' statically.' printf "%s\n" ' --enable-tcg-interpreter TCG with bytecode interpreter (slow)' printf "%s\n" ' --enable-trace-backends=CHOICES' printf "%s\n" ' Set available tracing backends [log] (choices:' @@ -71,6 +73,8 @@ meson_options_help() { printf "%s\n" ' [QEMU]' printf "%s\n" ' --qemu-ga-version=VALUE version number for qemu-ga installer' printf "%s\n" ' --smbd=VALUE Path to smbd for slirp networking' + printf "%s\n" ' --symcc-backend=VALUE SymCC backend to use. Please check SymCC Runtime' + printf "%s\n" ' for a list of available backends. [qsym]' printf "%s\n" ' --sysconfdir=VALUE Sysconf data directory [etc]' printf "%s\n" ' --tls-priority=VALUE Default TLS protocol/cipher priority string' printf "%s\n" ' [NORMAL]' @@ -488,6 +492,9 @@ _meson_option_parse() { --disable-stack-protector) printf "%s" -Dstack_protector=disabled ;; --enable-strip) printf "%s" -Dstrip=true ;; --disable-strip) printf "%s" -Dstrip=false ;; + --symcc-backend=*) quote_sh "-Dsymcc_backend=$2" ;; + --enable-symcc-shared) printf "%s" -Dsymcc_shared=true ;; + --disable-symcc-shared) printf "%s" -Dsymcc_shared=false ;; --sysconfdir=*) quote_sh "-Dsysconfdir=$2" ;; --enable-tcg) printf "%s" -Dtcg=enabled ;; --disable-tcg) printf "%s" -Dtcg=disabled ;;