Skip to content

Yale-PROCTOR/crat

Repository files navigation

Crat

C-originated Rust Advancing Transformer

Setup

There is no specific requirement to build and run Crat. Just make sure that you have Cargo installed.

Preparation

You should first build the deps_crate crate, which provides dependencies to compile the Rust program to be transformed. You only need to do this once.

cargo build --manifest-path deps_crate/Cargo.toml

Usage

Here, we explain an example workflow to translate a C project to Rust using C2Rust and Crat. The example project is a simple program that reads five integers from the standard input and prints their sum. The C source code is under examples/sum. In the following steps, we assume that the ~/rs and ~/rs-transformed directories exist. You may use other paths as you like.

First, run the following commands to create compile_commands.json using intercept-build:

cd examples/sum
intercept-build make
cd ../..

Then, run C2Rust to obtain the initial Rust code. c2rust-transpile should be on your PATH. We recommend using our custom version based on C2Rust 0.21.0. Make sure you check out the tractor-0.21.0 branch after cloning the repository.

c2rust-transpile -e -o ~/rs/sum examples/sum/compile_commands.json

This will create ~/rs/sum containing the generated Rust code.

Finally, run Crat to transform the Rust code:

cargo run --bin crat -- \
  -o ~/rs-transformed \
  --unsafe-remove-unused \
  --unsafe-remove-no-mangle \
  --unsafe-remove-extern-c \
  --unexpand-use-print \
  --bin-name sum \
  --pass expand,extern,preprocess,pointer,io,libc,static,simpl,unsafe,unexpand,split,bin \
  ~/rs/sum

This will create ~/rs-transformed/sum containing the transformed Rust code. Run the following commands to run the program:

echo 1 2 3 4 5 | cargo run --manifest-path ~/rs-transformed/sum/Cargo.toml

The expected output is as follows:

Sum: 15

Benchmarks

To compile and run benchmark programs, the following packages and tools are required:

apt-get install curl freeglut3-dev gcc git less libao-dev libasound2-dev \
  libavcodec-dev libavfilter-dev libavformat-dev libavutil-dev libc6-dev \
  libcrypt-dev libcurl4-gnutls-dev libev-dev libevent-dev libfftw3-dev \
  libfuse-dev libfuse3-dev libgcrypt20-dev libgl-dev libglu1-mesa-dev \
  libgmp-dev libidn2-dev libiniparser-dev libjson-c-dev liblzma-dev \
  libncurses-dev libpcap0.8-dev libpcre3-dev libpq-dev libpulse-dev \
  librdkafka-dev libreadline-dev librtlsdr-dev libselinux1-dev libssl-dev \
  libunistring-dev libusb-1.0-0-dev libwww-perl libx11-dev libxau-dev \
  libxcomposite-dev libxdamage-dev libxext-dev libxfixes-dev libxrandr-dev \
  libxrender-dev locales make nettle-dev php7.4-cli postgresql-server-dev-12 \
  pulseaudio redis-server squeezelite sudo time uuid-dev zlib1g-dev
pip install pytest cram

In addition, the username should be ubuntu, and using Ubuntu 20.04 is recommended.

You may use the kaistplrg/crat-test-user:1.1.2 Docker image, which meets the above requirements.

Benchmark programs are under benchmarks/rs. Each directory corresponds to each benchmark and contains Rust code generated by C2Rust. You can run Crat to transform the benchmark programs.

tool.py is a Python script that allows you to easily transform the benchmarks, build the transformed code, and run their test suites. It can be executed with a command of the following form:

./tool.py <command> <stage> <benchmark>

The command can be one of the following:

  • transform: Transform the benchmark program(s).
  • build: Build the transformed benchmark program(s).
  • test: Run the test suite of the transformed benchmark program(s).
  • clean: Remove the transformed benchmark program(s).

The stage specifies the directories being the source and the destination of the transformation and also the passes to be applied. The following stages are available:

  • expand: From rs to rs-expand by applying expand.
  • extern: From rs-expand to rs-extern by applying preprocess,extern.
  • extern-post: From rs-extern to rs-extern-post by applying unsafe,unexpand,split,bin.

The benchmark is the name of the benchmark program to be processed, which is the name of the directory under benchmarks/rs. For example, the following command processes the avl benchmark:

./tool.py transform expand avl

If the given name does not match any of them, any benchmark whose name starts with the given name will be processed. For example, the following command processes the proxychains and proxychains-ng benchmarks:

./tool.py transform expand proxy

The benchmark name is an optional argument. If no benchmark is specified, all benchmarks will be processed. For example, the following command processes all benchmarks:

./tool.py transform expand

You can use the --exclude option to exclude benchmarks whose names start with a certain prefix. This is especially useful when you want to process all benchmarks except for a few of them. For example, the following command processes all benchmarks except for proxychains and proxychains-ng:

./tool.py transform expand --exclude proxy

You can exclude multiple benchmarks by specifying the --exclude option multiple times or by separating the names with commas. For example, the following commands process all benchmarks except for avl, proxychains, and proxychains-ng:

./tool.py transform expand --exclude avl --exclude proxy
./tool.py transform expand --exclude avl,proxy

When processing multiple benchmarks, tool.py immediately aborts if any of them fails to be processed. To continue processing the remaining benchmarks even upon failure, use the --keep-going option:

./tool.py transform expand --keep-going

If there are failed benchmarks, tool.py will show the list of them at the end of the output.

Transform

The following command transforms avl to the expand stage:

./tool.py transform expand avl

This will not transform the code if benchmarks/rs-expand/avl already exists. To overwrite the existing code, use the --overwrite option:

./tool.py transform expand avl --overwrite

tool.py runs Crat in the release mode by default. If you want to run it in the debug mode, you need to set the DEBUG environment variable:

DEBUG=1 ./tool.py transform expand avl

This would be useful when inspecting the stack traces or frequently re-compiling Crat during development.

If the stage depends on another stage, the tool.py will automatically transform the required stage first if it has not been transformed yet. For example, the following command transforms avl to the expand stage if necessary, and then transforms it to the extern stage:

./tool.py transform extern avl

Note that the --overwrite option only applies to the last stage by default. Therefore, the following command never overwrites the expand stage:

./tool.py transform extern avl --overwrite

To overwrite other stages, you can increase the depth by using the --overwrite-depth option:

./tool.py transform extern avl --overwrite --overwrite-depth 2

The default depth is 1, and any positive integer is allowed. When max is given, all stages will be overwritten:

./tool.py transform extern avl --overwrite --overwrite-depth max

Build

The following command builds the transformed avl in the expand stage:

./tool.py build expand avl

This will automatically transform avl to the expand stage if it has not been transformed yet. To overwrite the existing code, use the --overwrite option:

./tool.py build expand avl --overwrite

tool.py builds the transformed code in the release mode by default. If you want to build it in the debug mode, use the --debug option:

./tool.py build expand avl --debug

Test

The following command runs the test suite of the transformed avl in the extern-post stage:

./tool.py test extern-post avl

As in build, --overwrite and --debug options can be used.

Clean

The following command remove the transformed avl in the expand stage:

./tool.py clean expand avl

When multiple benchmarks are to be cleaned at once, a confirmation prompt will be displayed before removing them. To skip the confirmation, use the --yes or -y option:

./tool.py clean expand --yes

About

C-originated Rust Advancing Transformer

Resources

License

Stars

Watchers

Forks

Contributors 4

  •  
  •  
  •  
  •