Skip to content

Commit

Permalink
r2c implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
Felix Berlakovich committed Jan 25, 2023
1 parent 1fdec59 commit e4a85b9
Show file tree
Hide file tree
Showing 118 changed files with 4,716 additions and 288 deletions.
138 changes: 41 additions & 97 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,110 +1,54 @@
# The LLVM Compiler Infrastructure
# R2C

This directory and its sub-directories contain source code for LLVM,
a toolkit for the construction of highly optimized compilers,
optimizers, and run-time environments.
## Benchmarking
If you want to run the benchmarks, follow the instructions from https://github.com/fberlakovich/r2c-benchmarking.
The repository contains benchmarking infrastructure that automatically builds the R²C compiler and runs SPEC CPU 2017 and webserver benchmarks.

The README briefly describes how to get started with building LLVM.
For more information on how to contribute to the LLVM project, please
take a look at the
[Contributing to LLVM](https://llvm.org/docs/Contributing.html) guide.
## Building Webservers
To build the webservers, you need a fully built version of the R²C compiler.
If you have run the benchmarks with the benchmarking infrastructure already, you can reuse compiler already built.
Alternatively, you can manually build the compiler.

## Getting Started with the LLVM System
> **WARNING**: Building the webservers requires *a lot* of CPU and memory, especially when using a large number of parallel build jobs.
> This is especially true because the R²C compiler was not optimized for compilation speed.
> If you encounter OOM errors, try building with fewer parallel jobs.
Taken from https://llvm.org/docs/GettingStarted.html.
### Reusing the compiler build from the benchmarking infrastructure
You can find the built compiler in `<benchmarking-dir>/build/packages/llvm-src-13.0.0/obj/bin`, where `<benchmarking-dir>` is the directory with the `r2c-benchmarking` code.
Note that you will find this directory only if you have at least benchmark before (see the `r2c-benchmarking` repository for details).

### Overview
### Building the compiler manually
1. clone this repository
1. checkout branch `r2c`
1. make sure you have the gold linker installed and set as the system default linker
1. create a build directory
1. `cd <build-dir>`
1. build the compiler
1. For a debug build: `cmake -G Ninja -DLLVM_ENABLE_PROJECTS='clang;compiler-rt' -DLLVM_ENABLE_ASSERTIONS=TRUE -DCMAKE_BUILD_TYPE=Debug -DCMAKE_SHARED_LINKER_FLAGS='-Wl,--gdb-index' -DCMAKE_EXE_LINKER_FLAGS='-Wl,--gdb-index' -DBUILD_SHARED_LIBS=true -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BINUTILS_INCDIR=/usr/include <src-dir>/llvm`
2. For a release build: `cmake -G Ninja -DLLVM_ENABLE_PROJECTS="clang;compiler-rt" -DLLVM_ENABLE_ASSERTIONS=TRUE -DBUILD_SHARED_LIBS=true -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BINUTILS_INCDIR=/usr/include <src-dir>/llvm`
1. ninja -j <number of parallel jobs>

Welcome to the LLVM project!

The LLVM project has multiple components. The core of the project is
itself called "LLVM". This contains all of the tools, libraries, and header
files needed to process intermediate representations and converts it into
object files. Tools include an assembler, disassembler, bitcode analyzer, and
bitcode optimizer. It also contains basic regression tests.
### Building Webkit

C-like languages use the [Clang](http://clang.llvm.org/) front end. This
component compiles C, C++, Objective-C, and Objective-C++ code into LLVM bitcode
-- and from there into object files, using LLVM.
To build the GTK version with R²C protections enabled, follow these instructions:

Other components include:
the [libc++ C++ standard library](https://libcxx.llvm.org),
the [LLD linker](https://lld.llvm.org), and more.
1. Fetch the Webkit source from https://github.com/fberlakovich/Webkit, e.g., to `webkit/src`

### Getting the Source Code and Building LLVM
The repository contains the version of Webkit we built for the paper plus a commit with the required modifications.
See the Limitations section in the paper for why the modifications are neccessary.
1. Make sure to install all the dependencies required to build Webkit (see https://trac.webkit.org/wiki/BuildingGtk#Dependencies)
1. Create a build directory, e.g., `webkit/build` and run cmake with the following options

The LLVM Getting Started documentation may be out of date. The [Clang
Getting Started](http://clang.llvm.org/get_started.html) page might have more
accurate information.
``
export COMPILER_FLAGS="-flto=thin -O3 -fbtras=10 -fheap-boobytraps=10" export LDFLAGS="-flto=thin -Wl,--plugin-opt,-fast-isel=false -fbtras=10 -fheap-boobytraps=10 -Wl,--plugin-opt,-assume-btra-callee=maybe -Wl,--plugin-opt,-prolog-min-padding-instructions=1 -Wl,--plugin-opt,-prolog-max-padding-instructions=5 -Wl,--plugin-opt,-shuffle-functions=true -Wl,--plugin-opt,-shuffle-globals=true -Wl,--plugin-opt,-randomize-reg-alloc=true" && cmake -DCMAKE_C_COMPILER:FILEPATH=<llvm-build>/bin/clang -DCMAKE_RANLIB=<llvm-build>/bin/llvm-ranlib -DCMAKE_NM=<llvm-build>/bin/llvm-nm -DCMAKE_AR=<llvm-build>/bin/llvm-ar -DCMAKE_CXX_COMPILER:FILEPATH=<llvm-build>/bin/clang++ -DCMAKE_C_FLAGS=$COMPILER_FLAGS -DCMAKE_CXX_FLAGS=$COMPILER_FLAGS -DPORT="GTK" -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_BUILD_TYPE=Release -G Ninja -DUSE_WPE_RENDERER=Off -DENABLE_GAMEPAD=OFF -DDEVELOPER_MODE=ON -DENABLE_EXPERIMENTAL_FEATURES=ON "<webkit-src>"
``

Make sure to replace
1. `<llvm-build>` with your LLVM build directory
2. `<webkit-src>` with your Webkit source directory

This is an example work-flow and configuration to get and build the LLVM source:
1. Run `ninja`

1. Checkout LLVM (including related sub-projects like Clang):

* ``git clone https://github.com/llvm/llvm-project.git``

* Or, on windows, ``git clone --config core.autocrlf=false
https://github.com/llvm/llvm-project.git``

2. Configure and build LLVM and Clang:

* ``cd llvm-project``

* ``mkdir build``

* ``cd build``

* ``cmake -G <generator> [options] ../llvm``

Some common build system generators are:

* ``Ninja`` --- for generating [Ninja](https://ninja-build.org)
build files. Most llvm developers use Ninja.
* ``Unix Makefiles`` --- for generating make-compatible parallel makefiles.
* ``Visual Studio`` --- for generating Visual Studio projects and
solutions.
* ``Xcode`` --- for generating Xcode projects.

Some Common options:

* ``-DLLVM_ENABLE_PROJECTS='...'`` --- semicolon-separated list of the LLVM
sub-projects you'd like to additionally build. Can include any of: clang,
clang-tools-extra, libcxx, libcxxabi, libunwind, lldb, compiler-rt, lld,
polly, or debuginfo-tests.

For example, to build LLVM, Clang, libcxx, and libcxxabi, use
``-DLLVM_ENABLE_PROJECTS="clang;libcxx;libcxxabi"``.

* ``-DCMAKE_INSTALL_PREFIX=directory`` --- Specify for *directory* the full
path name of where you want the LLVM tools and libraries to be installed
(default ``/usr/local``).

* ``-DCMAKE_BUILD_TYPE=type`` --- Valid options for *type* are Debug,
Release, RelWithDebInfo, and MinSizeRel. Default is Debug.

* ``-DLLVM_ENABLE_ASSERTIONS=On`` --- Compile with assertion checks enabled
(default is Yes for Debug builds, No for all other build types).

* ``cmake --build . [-- [options] <target>]`` or your build system specified above
directly.

* The default target (i.e. ``ninja`` or ``make``) will build all of LLVM.

* The ``check-all`` target (i.e. ``ninja check-all``) will run the
regression tests to ensure everything is in working order.

* CMake will generate targets for each tool and library, and most
LLVM sub-projects generate their own ``check-<project>`` target.

* Running a serial build will be **slow**. To improve speed, try running a
parallel build. That's done by default in Ninja; for ``make``, use the option
``-j NNN``, where ``NNN`` is the number of parallel jobs, e.g. the number of
CPUs you have.

* For more information see [CMake](https://llvm.org/docs/CMake.html)

Consult the
[Getting Started with LLVM](https://llvm.org/docs/GettingStarted.html#getting-started-with-llvm)
page for detailed information on configuring and compiling LLVM. You can visit
[Directory Layout](https://llvm.org/docs/GettingStarted.html#directory-layout)
to learn about the layout of the source code tree.
After building successfully, you will find the binaries below the `bin` directory.
You can run the tests, by running one of the `test*` binaries or start the browser by running `MiniBrowser`.
6 changes: 6 additions & 0 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -3438,6 +3438,12 @@ defm stack_arrays : BooleanFFlag<"stack-arrays">, Group<gfortran_Group>;
defm underscoring : BooleanFFlag<"underscoring">, Group<gfortran_Group>;
defm whole_file : BooleanFFlag<"whole-file">, Group<gfortran_Group>;

def r2c_Group : OptionGroup<"R2C Group">;
def fheap_boobytraps : Joined<["-"], "fheap-boobytraps=">, Group<r2c_Group>;
def fbtras : Joined<["-"], "fbtras=">, Group<r2c_Group>;
defm harden_heap_boobytraps : BooleanFFlag<"harden-heap-boobytraps">, Group<r2c_Group>;


// C++ SYCL options
def fsycl : Flag<["-"], "fsycl">, Group<sycl_Group>, Flags<[CC1Option, CoreOption]>,
HelpText<"Enable SYCL kernels compilation for device">;
Expand Down
7 changes: 7 additions & 0 deletions clang/lib/Driver/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1121,6 +1121,13 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) {
.Default(SaveTempsCwd);
}

// expand TARGET in sysroot path
if (!SysRoot.empty()) {
size_t pos{0};
while ((pos = SysRoot.find("TARGET", pos)) != std::string::npos)
SysRoot.replace(pos, 6, TargetTriple);
}

setLTOMode(Args);

// Process -fembed-bitcode= flags.
Expand Down
19 changes: 19 additions & 0 deletions clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6192,6 +6192,25 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back(Args.MakeArgString(Str));
}

if (Args.hasArg(options::OPT_fbtras)) {
CmdArgs.push_back("-mllvm");
CmdArgs.push_back(Args.MakeArgString("-diversity-mode=3"));
}

if (Args.hasArg(options::OPT_fheap_boobytraps)) {
StringRef HeapBoobyTraps = Args.getLastArg(options::OPT_fheap_boobytraps)->getValue();
bool dontHarden =
!Args.hasFlag(options::OPT_fharden_heap_boobytraps,
options::OPT_fno_harden_heap_boobytraps, true);

CmdArgs.push_back("-mllvm");
CmdArgs.push_back(Args.MakeArgString("-max-heap-ptr-boobytraps=" + Twine(HeapBoobyTraps)));
if (dontHarden) {
CmdArgs.push_back("-mllvm");
CmdArgs.push_back(Args.MakeArgString("-harden-heap-boobytraps=false"));
}
}

// Add the "-o out -x type src.c" flags last. This is done primarily to make
// the -cc1 command easier to edit when reproducing compiler crashes.
if (Output.getType() == types::TY_Dependencies) {
Expand Down
42 changes: 42 additions & 0 deletions clang/lib/Driver/ToolChains/CommonArgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "clang/Driver/ToolChain.h"
#include "clang/Driver/Util.h"
#include "clang/Driver/XRayArgs.h"
#include "clang/Driver/OptionUtils.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
Expand Down Expand Up @@ -387,6 +388,25 @@ bool tools::isUseSeparateSections(const llvm::Triple &Triple) {
return Triple.getOS() == llvm::Triple::CloudABI;
}

void tools::addBoobyTrapRT(const ToolChain &TC, const ArgList &Args,
ArgStringList &CmdArgs) {
CmdArgs.push_back("-whole-archive");
CmdArgs.push_back(TC.getCompilerRTArgString(Args, "boobytraps"));
CmdArgs.push_back("-no-whole-archive");
}


void tools::addHeapBoobyTrapRT(const ToolChain &TC, const ArgList &Args,
ArgStringList &CmdArgs) {
CmdArgs.push_back("-whole-archive");
if (Args.hasFlag(options::OPT_fharden_heap_boobytraps, options::OPT_fno_harden_heap_boobytraps, true)) {
CmdArgs.push_back(TC.getCompilerRTArgString(Args, "hardened_heap_boobytraps"));
} else {
CmdArgs.push_back(TC.getCompilerRTArgString(Args, "heap_boobytraps"));
}
CmdArgs.push_back("-no-whole-archive");
}

void tools::addLTOOptions(const ToolChain &ToolChain, const ArgList &Args,
ArgStringList &CmdArgs, const InputInfo &Output,
const InputInfo &Input, bool IsThinLTO) {
Expand Down Expand Up @@ -466,6 +486,28 @@ void tools::addLTOOptions(const ToolChain &ToolChain, const ArgList &Args,
CmdArgs.push_back("-plugin-opt=-debugger-tune=gdb");
}

if (Args.hasArg(options::OPT_fbtras)) {
StringRef BTRAs = Args.getLastArg(options::OPT_fbtras)->getValue();
CmdArgs.push_back(Args.MakeArgString("-plugin-opt=-diversity-mode=3"));
CmdArgs.push_back(
Args.MakeArgString("-plugin-opt=-num-btras=" + Twine(BTRAs)));
}

if (Args.hasArg(options::OPT_fheap_boobytraps)) {
StringRef HeapBoobyTraps =
Args.getLastArg(options::OPT_fheap_boobytraps)->getValue();
bool dontHarden =
!Args.hasFlag(options::OPT_fharden_heap_boobytraps,
options::OPT_fno_harden_heap_boobytraps, true);

if (dontHarden) {
CmdArgs.push_back(
Args.MakeArgString("-plugin-opt=-harden-heap-boobytraps=false"));
}
CmdArgs.push_back(Args.MakeArgString(
"-plugin-opt=-max-heap-ptr-boobytraps=" + Twine(HeapBoobyTraps)));
}

bool UseSeparateSections =
isUseSeparateSections(ToolChain.getEffectiveTriple());

Expand Down
5 changes: 5 additions & 0 deletions clang/lib/Driver/ToolChains/CommonArgs.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,11 @@ void addMultilibFlag(bool Enabled, const char *const Flag,

void addX86AlignBranchArgs(const Driver &D, const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs, bool IsLTO);
void addBoobyTrapRT(const ToolChain &TC, const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs);

void addHeapBoobyTrapRT(const ToolChain &TC, const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs);
} // end namespace tools
} // end namespace driver
} // end namespace clang
Expand Down
15 changes: 15 additions & 0 deletions clang/lib/Driver/ToolChains/Gnu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "llvm/Support/Path.h"
#include "llvm/Support/TargetParser.h"
#include "llvm/Support/VirtualFileSystem.h"
#include <clang/Driver/OptionUtils.h>
#include <system_error>

using namespace clang::driver;
Expand Down Expand Up @@ -563,6 +564,20 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
D.getLTOMode() == LTOK_Thin);
}

if (Args.hasArg(options::OPT_fheap_boobytraps)) {
unsigned NumHeapBoobyTraps = getLastArgIntValue(Args, options::OPT_fheap_boobytraps, 0);
if (NumHeapBoobyTraps > 0) {
addHeapBoobyTrapRT(ToolChain, Args, CmdArgs);
}
}

if (Args.hasArg(options::OPT_fbtras)) {
unsigned NumBTRAs = getLastArgIntValue(Args, options::OPT_fbtras, 0);
if (NumBTRAs > 0) {
addBoobyTrapRT(ToolChain, Args, CmdArgs);
}
}

if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle))
CmdArgs.push_back("--no-demangle");

Expand Down
1 change: 1 addition & 0 deletions compiler-rt/cmake/config-ix.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ set(ALL_TSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64} ${PPC64})
set(ALL_UBSAN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${RISCV64}
${MIPS32} ${MIPS64} ${PPC64} ${S390X} ${SPARC} ${SPARCV9})
set(ALL_SAFESTACK_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM64} ${MIPS32} ${MIPS64})
set(ALL_R2C_SUPPORTED_ARCH ${X86_64})
set(ALL_CFI_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${MIPS64})
set(ALL_SCUDO_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${MIPS32} ${MIPS64} ${PPC64})
set(ALL_SCUDO_STANDALONE_SUPPORTED_ARCH ${X86} ${X86_64})
Expand Down
2 changes: 2 additions & 0 deletions compiler-rt/lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,5 @@ endif()
# is true for fuzzers that exercise parts of the runtime. So we add the fuzzer
# directories explicitly here.
add_subdirectory(scudo/standalone/fuzz)

add_subdirectory(r2c)
46 changes: 46 additions & 0 deletions compiler-rt/lib/r2c/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
add_compiler_rt_component(heap_boobytraps)
add_compiler_rt_component(hardened_heap_boobytraps)
add_compiler_rt_component(boobytraps)

set(HEAPBOOBYTRAPS_SOURCES
heap_boobytraps.c
heapbt_common.c
)

set(HARDENEDHEAPBOOBYTRAPS_SOURCES
hardened_heap_boobytraps.c
heapbt_common.c
)

set(BOOBYTRAPS_SOURCES
boobytraps.c
)


include_directories(..)

foreach(arch ${ALL_R2C_SUPPORTED_ARCH})
message(STATUS "Building boobytraps RT library for ${arch}")
add_compiler_rt_runtime(clang_rt.boobytraps
STATIC
ARCHS ${arch}
SOURCES ${BOOBYTRAPS_SOURCES}
CFLAGS ${BOOBYTRAPS_CFLAGS}
PARENT_TARGET boobytraps)

message(STATUS "Building heap boobytrap RT library for ${arch}")
add_compiler_rt_runtime(clang_rt.heap_boobytraps
STATIC
ARCHS ${arch}
SOURCES ${HEAPBOOBYTRAPS_SOURCES}
CFLAGS ${HEAPBOOBYTRAPS_CFLAGS}
PARENT_TARGET heap_boobytraps)

message(STATUS "Building hardened heap boobytrap RT library for ${arch}")
add_compiler_rt_runtime(clang_rt.hardened_heap_boobytraps
STATIC
ARCHS ${arch}
SOURCES ${HARDENEDHEAPBOOBYTRAPS_SOURCES}
CFLAGS ${HARDENEDHEAPBOOBYTRAPS_CFLAGS}
PARENT_TARGET hardened_heap_boobytraps)
endforeach()
12 changes: 12 additions & 0 deletions compiler-rt/lib/r2c/boobytraps.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//
// Created by felixl on 28/04/22.
//

#include <stdio.h>
#include <stdlib.h>

__attribute__((unused))
void ReportAttack() {
printf("A booby trap function was hit\n");
abort();
}

0 comments on commit e4a85b9

Please sign in to comment.