Skip to content

Commit

Permalink
Add some useful script and various changes
Browse files Browse the repository at this point in the history
Add a number of useful scripts:
* Scripts to compile the project, for `cheri` and `linux`
  configurations;
* Script to run `clang-format`;
* Script to execute a native executable multiple times in a shell
  script;
* Script to run full benchmarking, from compiling in release mode, to
  gathering data locally.

Add a variant of the compartment manager which executes the given
compartment multiple times. To be used in conjunction with
`multi_execute.sh` and the `EXECUTE_COUNT` environment variable for
benchmarking.

Some fixes and optimisations:
* Implement compartment unmapping, and integrate it into the cleaning
  process (add one relevant test)
* Merge `comp_map` `mmap`s into one
* Replace compartment parsing `pread`s with a single `mmap` and various
  memory operations
* Fix overflow when copying `environ` data from manager to compartment
* Enable `-Werror` only in `DEBUG` builds
  • Loading branch information
0152la committed Oct 31, 2024
1 parent e0c0e12 commit ed582b7
Show file tree
Hide file tree
Showing 13 changed files with 395 additions and 86 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.16)
project(CHERI_ELF_Compartments LANGUAGES C ASM)

# Set global compilation options
add_compile_options(-pedantic -Wextra -Wno-gnu-binary-literal -Wno-language-extension-token -Werror)
add_compile_options(-pedantic -Wextra -Wno-gnu-binary-literal -Wno-language-extension-token $<$<CONFIG:Debug>:-Werror>)

# Set useful directory variables
set(TEST_DIR ${CMAKE_SOURCE_DIR}/tests)
Expand Down
6 changes: 6 additions & 0 deletions include/compartment.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,10 @@ struct CompConfig
struct CompEntryPointDef *entry_points;
size_t entry_point_count;
void *base_address;

char** env_ptr;
size_t env_ptr_sz;
unsigned short env_ptr_count;
};

/**
Expand Down Expand Up @@ -219,6 +223,8 @@ comp_from_elf(char *, struct CompConfig *); // char **, size_t, void *);
void
comp_map(struct Compartment *);
void
comp_unmap(struct Compartment *);
void
comp_map_full(struct Compartment *);
int64_t
comp_exec(struct Compartment *, char *, void *, size_t);
Expand Down
32 changes: 32 additions & 0 deletions scripts/compile-cheri.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/bin/bash
set -e
set -x

# CheriBSD
export CC=/home/cheriworker/cheri/output/morello-sdk/bin/clang
export AR=/home/cheriworker/cheri/output/morello-sdk/bin/llvm-ar
export CFLAGS="--config cheribsd-morello-hybrid.cfg -DARM -O0"
export ASMFLAGS="--config cheribsd-morello-hybrid.cfg"
export LDFLAGS="--config cheribsd-morello-hybrid.cfg"

# Morello Linux Glibc
#export CC=/home/cheriworker/morello-glibc/arm-gnu-toolchain-10.1.morello-alp2-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-gcc
#export AR=/home/cheriworker/morello-glibc/arm-gnu-toolchain-10.1.morello-alp2-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-ar
#export CFLAGS="-march=morello"
#export ASMFLAGS="-march=morello"
#export LDFLAGS="-march=morello"

# Morello Linux

#export CC=clang
#export CFLAGS="-DX86"

build_dir="$(pwd)/build"
src_dir="$(pwd)/"

cmake \
-G Ninja \
-DCMAKE_BUILD_TYPE=DEBUG \
-B $build_dir \
-S $src_dir
cmake --build $build_dir -v
43 changes: 43 additions & 0 deletions scripts/compile-linux.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#!/bin/bash

#export CC=/home/cheriworker/cheri/output/morello-sdk/bin/clang
#export AR=/home/cheriworker/cheri/output/morello-sdk/bin/llvm-ar

export CC=clang
export AR=llvm-ar-10
#export CFLAGS="-fsanitize=address"

src_dir=/home/cheriworker/workspace/CHERI-ELF-comp
build_dir=$src_dir/build-linux
third_party_dir=$src_dir/third-party
comp_libs_dir=$build_dir/libs
sys_lib=/lib/x86_64-linux-gnu

cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug -B $build_dir -S $src_dir
cmake --build $build_dir --target comp_harness so_harness
cmake --build $build_dir --target lua_script simple_thrloc_var simple_const_thrloc_var simple


mkdir -p $comp_libs_dir

libs=(
$build_dir/src/libcomputils.so
$third_party_dir/lua/liblua.so
$sys_lib/libdl.so.2
$sys_lib/libm.so.6
$sys_lib/libc.so.6
/lib64/ld-linux-x86-64.so.2
)
for lib in ${libs[@]}
do
if [ -f $comp_libs_dir/$(basename $lib) ]
then
continue
fi
if [ ! -f $lib ]
then
echo "Did not find $lib!"
exit
fi
cp $lib $comp_libs_dir
done
131 changes: 131 additions & 0 deletions scripts/do_benchmarks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
#!/usr/bin/env python3

import datetime
import os
import shlex
import subprocess

from fabric import Connection

################################################################################
# Constants
################################################################################

BENCH_HOST = "10.81.18.119"
BENCH_USER = "al2510"

BENCH_RUN_PATH = "/home/0152la/bench-script"
BENCH_RUN_LIBS_PATH = f"{BENCH_RUN_PATH}/libs"

SRC_DIR = os.getcwd()
BUILD_DIR = f"{SRC_DIR}/build-release"
BUILD_TESTS_DIR = f"{BUILD_DIR}/tests"
SRC_TESTS_DIR = f"{SRC_DIR}/tests"
SCRIPTS_DIR = f"{SRC_DIR}/scripts"
RESULTS_DIR = f"{BUILD_DIR}/results-{datetime.datetime.now().strftime('%Y%m%d-%H%M%S')}"

THIRD_PARTY_DIR = f"{SRC_DIR}/third-party"
LUA_DIR = f"{THIRD_PARTY_DIR}/lua"

CMAKE_BUILD_ENV = {
**os.environ,
"CC": "/home/cheriworker/cheri/output/morello-sdk/bin/clang",
"AR": "/home/cheriworker/cheri/output/morello-sdk/bin/llvm-ar",
"CFLAGS": "--config cheribsd-morello-hybrid.cfg -DARM -O3",
"ASMFLAGS": "--config cheribsd-morello-hybrid.cfg",
"LDFLAGS": "--config cheribsd-morello-hybrid.cfg"
}

BENCH_RUN_ENV = {
"COMP_LIBRARY_PATH": f"{BENCH_RUN_PATH}/libs",
"LD_64_LIBRARY_PATH": f"{BENCH_RUN_PATH}/libs",
"EXECUTE_COUNT": 1000,
}

TESTS = [
"lua_script"
]

LOCAL_LIBS = [
f"{THIRD_PARTY_DIR}/lua/liblua.so",
f"{BUILD_DIR}/src/libcomputils.so",
]
REMOTE_LIBS = [
"/usr/lib64/libc.so.7",
"/usr/lib64/libdl.so.1",
"/usr/lib64/libm.so.5",
]

BENCH_BINS = [
f"{SCRIPTS_DIR}/multi_execute.sh",
f"{BUILD_TESTS_DIR}/manager_call_multi",
f"{SRC_TESTS_DIR}/hello_world.lua"
]
BENCH_EXECUTIONS = {
"native_multi": "multi_execute.sh ./lua_script",
"manager_multi": "manager_call_multi ./lua_script.so",
}

################################################################################
# Helper functions
################################################################################

def remote_put(conn, file, dest):
conn.put(file, remote = dest)

def remote_exec(conn, cmd, env = None, out = None):
return conn.run(cmd, env = env, echo = True, warn = True)

def remote_exec_log(conn, cmd, env, out):
return conn.run(cmd, env = env, echo = True, warn = True, out_stream = out, hide = 'stdout')

def remote_exec_log_err(conn, cmd, env, out):
return conn.run(cmd, env = env, echo = True, warn = True, err_stream = out, hide = 'stdout')

################################################################################
# Main
################################################################################


# Compile project
cmake_cmd = f"cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -B {BUILD_DIR} -S {SRC_DIR}"
subprocess.run(shlex.split(cmake_cmd), env = CMAKE_BUILD_ENV)
cmake_cmd = f"cmake --build {BUILD_DIR}"
subprocess.run(shlex.split(cmake_cmd), env = CMAKE_BUILD_ENV)

# Compile native tests
native_build_flags = f"-I{LUA_DIR} -L{LUA_DIR} -llua"
native_build_cmd = f"{CMAKE_BUILD_ENV['CC']} {CMAKE_BUILD_ENV['CFLAGS']} -o {BUILD_TESTS_DIR}/{{0}} {SRC_TESTS_DIR}/{{0}}.c {native_build_flags}"
for test in TESTS:
cmd = shlex.split(native_build_cmd.format(test))
subprocess.run(cmd)

# Prepare results folder
os.makedirs(RESULTS_DIR, exist_ok = True)

# Copy tests and scripts
conn = Connection(host = BENCH_HOST, user = BENCH_USER, inline_ssh_env = True)
remote_exec(conn, f"mkdir -p {BENCH_RUN_LIBS_PATH}")

for test in TESTS:
remote_put(conn, f"{BUILD_TESTS_DIR}/{test}", BENCH_RUN_PATH)
remote_put(conn, f"{BUILD_TESTS_DIR}/{test}.so", BENCH_RUN_PATH)
for bbin in BENCH_BINS:
remote_put(conn, bbin, BENCH_RUN_PATH)
for llib in LOCAL_LIBS:
remote_put(conn, llib, BENCH_RUN_LIBS_PATH)
for rlib in REMOTE_LIBS:
remote_exec(conn, f"ln -sf {rlib} {BENCH_RUN_LIBS_PATH}")

# Execute benchmarks
for key, cmd in BENCH_EXECUTIONS.items():
cmd = f"cd {BENCH_RUN_PATH} ; truss -c ./{cmd}"
with open(f"{RESULTS_DIR}/truss-{key}", 'w') as res_fd:
remote_exec_log_err(conn, cmd, env = BENCH_RUN_ENV, out = res_fd)

cmd = f"cd {BENCH_RUN_PATH} ; hyperfine"
cmd = ' '.join([cmd, *[f"'./{x}'" for x in BENCH_EXECUTIONS.values()]])
with open(f"{RESULTS_DIR}/hyperfine", 'w') as res_fd:
remote_exec_log(conn, cmd, env = BENCH_RUN_ENV, out = res_fd)

conn.close()
2 changes: 2 additions & 0 deletions scripts/do_clang_format.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/bin/bash
clang-format -i ./src/*.c ./include/*.h ./tests/*.c
14 changes: 14 additions & 0 deletions scripts/multi_execute.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/bin/sh

if [ $# -ne 1 ]
then
echo "Expected exactly one argument: test to execute!"
exit 1
fi

EXECUTE_COUNT=${EXECUTE_COUNT:=100}

for i in $(seq 1 $EXECUTE_COUNT)
do
./$1
done
Loading

0 comments on commit ed582b7

Please sign in to comment.