Skip to content

Commit

Permalink
SymCC Runtime Integration
Browse files Browse the repository at this point in the history
* 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.
  • Loading branch information
rmalmain committed Apr 4, 2024
1 parent a15cf39 commit 5af4c68
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 57 deletions.
42 changes: 12 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
```

Expand All @@ -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
Expand Down Expand Up @@ -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 .
```
Expand Down
21 changes: 0 additions & 21 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -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=""
Expand Down Expand Up @@ -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=*|\
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
38 changes: 32 additions & 6 deletions meson.build
Original file line number Diff line number Diff line change
@@ -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'))

Expand All @@ -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')
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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')
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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'
Expand Down Expand Up @@ -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}
Expand Down
6 changes: 6 additions & 0 deletions meson_options.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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.')
7 changes: 7 additions & 0 deletions scripts/meson-buildoptions.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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:'
Expand All @@ -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]'
Expand Down Expand Up @@ -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 ;;
Expand Down

0 comments on commit 5af4c68

Please sign in to comment.