454 lines
15 KiB
Makefile
454 lines
15 KiB
Makefile
BUILD_DIR := "build"
|
|
|
|
# Load environment variables set by "nix develop"-shell
|
|
|
|
FAIL_SHARE := env("FAIL_SHARE")
|
|
WASI_ROOT := env("WASI_ROOT")
|
|
WAMR_ROOT := env("WAMR_ROOT")
|
|
LIBIWASM_DEBUG := env("LIBIWASM_DEBUG")
|
|
LIBIWASM_RELEASE := env("LIBIWASM_RELEASE")
|
|
LIBIWASM_LINUX_DEBUG := env("LIBIWASM_LINUX_DEBUG")
|
|
LIBIWASM_LINUX_RELEASE := env("LIBIWASM_LINUX_RELEASE")
|
|
CROSS_CC := env("CROSS_CC")
|
|
LINUX_CC := env("LINUX_CC")
|
|
|
|
# =================================================================================================================== #
|
|
# Helper recipes
|
|
# =================================================================================================================== #
|
|
|
|
[default]
|
|
[private]
|
|
list:
|
|
@just --list --unsorted
|
|
|
|
[private]
|
|
create-build-dir module:
|
|
mkdir -p {{ BUILD_DIR }}-{{ module }}
|
|
|
|
[doc("Delete the build directory")]
|
|
clean module:
|
|
rm -rf {{ BUILD_DIR }}-{{ module }}
|
|
|
|
# =================================================================================================================== #
|
|
# Build WASM module recipes
|
|
# =================================================================================================================== #
|
|
|
|
WASI_CC := f"{{WASI_ROOT}}/bin/clang"
|
|
WASI_CFLAGS := "\
|
|
--target=wasm32 \
|
|
--sysroot={{WASI_ROOT}}/share/wasi-sysroot \
|
|
-z stack-size=4096 \
|
|
-O0 \
|
|
-nostdlib \
|
|
-Wl,--no-entry \
|
|
-Wl,--export-all \
|
|
-Wl,--no-gc-sections \
|
|
-Wl,--initial-memory=65536 \
|
|
-Wl,--export=__heap_base \
|
|
-Wl,--export=__data_end \
|
|
"
|
|
WAMRC := "wamrc"
|
|
WAMRCFLAGS := "\
|
|
--target=i386 \
|
|
--cpu=generic \
|
|
--opt-level=0 \
|
|
"
|
|
XXD := "xxd"
|
|
|
|
[doc("C -> WASM: Compile a C function to a WASM module using WASI-SDK")]
|
|
[group("build-module")]
|
|
build-wasm-module module: (create-build-dir module)
|
|
{{ WASI_CC }} {{ WASI_CFLAGS }} targets/wasm-module/{{ module }}.c -o {{ BUILD_DIR }}-{{ module }}/wasm_module.wasm
|
|
|
|
[doc("WASM -> AOT: Compile a WASM module ahead-of-time using WAMR")]
|
|
[group("build-module")]
|
|
build-wasm-aot module: (build-wasm-module module)
|
|
{{ WAMRC }} {{ WAMRCFLAGS }} -o {{ BUILD_DIR }}-{{ module }}/wasm_module.aot {{ BUILD_DIR }}-{{ module }}/wasm_module.wasm
|
|
|
|
[doc("AOT -> C-Array: Dump a WASM module compiled ahead-of-time to a binary array")]
|
|
[group("build-module")]
|
|
build-wasm-aot-array module: (build-wasm-aot module)
|
|
{{ XXD }} -i {{ BUILD_DIR }}-{{ module }}/wasm_module.aot > {{ BUILD_DIR }}-{{ module }}/wasm_module_array.c
|
|
|
|
# =================================================================================================================== #
|
|
# Host program recipes
|
|
# =================================================================================================================== #
|
|
# FAIL*
|
|
|
|
CROSS_CFLAGS := "\
|
|
-I./targets/wasm-host \
|
|
-O2 \
|
|
-m32 \
|
|
-ffunction-sections \
|
|
-fdata-sections \
|
|
-ffreestanding \
|
|
-fomit-frame-pointer \
|
|
-ggdb \
|
|
"
|
|
CROSS_LDFLAGS := f"\
|
|
-Wl,--build-id=none \
|
|
-static \
|
|
-nostdlib \
|
|
-m32 \
|
|
-L{{LIBIWASM_RELEASE}} \
|
|
-liwasm \
|
|
-lc \
|
|
-lgcc \
|
|
-lm \
|
|
"
|
|
CROSS_INCLUDES := f"\
|
|
-I{{WAMR_ROOT}}/core/iwasm/include \
|
|
-I{{WAMR_ROOT}}/core/shared/utils \
|
|
-I{{WAMR_ROOT}}/core/shared/platform/baremetal \
|
|
"
|
|
|
|
# LINUX-POSIX
|
|
|
|
LINUX_CFLAGS := "\
|
|
-I./targets/wasm-host \
|
|
-O0 \
|
|
-m32 \
|
|
-ffunction-sections \
|
|
-fdata-sections \
|
|
-ggdb \
|
|
"
|
|
LINUX_LDFLAGS := f"\
|
|
-Wl,--build-id=none \
|
|
-m32 \
|
|
-Wl,-rpath,{{LIBIWASM_LINUX_DEBUG}} \
|
|
-L{{LIBIWASM_LINUX_DEBUG}} \
|
|
-liwasm \
|
|
-lm \
|
|
"
|
|
LINUX_INCLUDES := f"\
|
|
-I{{WAMR_ROOT}}/core/iwasm/include \
|
|
-I{{WAMR_ROOT}}/core/shared/utils \
|
|
-I{{WAMR_ROOT}}/core/shared/platform/linux \
|
|
"
|
|
|
|
# LINUX-Baremetal
|
|
|
|
LINUX_BAREMETAL_CFLAGS := "\
|
|
-I./targets/wasm-host \
|
|
-O0 \
|
|
-m32 \
|
|
-ffunction-sections \
|
|
-fdata-sections \
|
|
-ffreestanding \
|
|
-ggdb \
|
|
"
|
|
LINUX_BAREMETAL_LDFLAGS := f"\
|
|
-Wl,--build-id=none \
|
|
-static \
|
|
-nostdlib \
|
|
-m32 \
|
|
-L{{LIBIWASM_DEBUG}} \
|
|
-liwasm \
|
|
-lc \
|
|
-lgcc \
|
|
-lm \
|
|
--entry main \
|
|
"
|
|
LINUX_BAREMETAL_INCLUDES := f"\
|
|
-I{{WAMR_ROOT}}/core/iwasm/include \
|
|
-I{{WAMR_ROOT}}/core/shared/utils \
|
|
-I{{WAMR_ROOT}}/core/shared/platform/baremetal \
|
|
"
|
|
|
|
# TODO: Grave mistake to template the commands depending on the target... Should've used shebang recipes instead
|
|
|
|
[private]
|
|
build-wasm-host-fail module:
|
|
{{ CROSS_CC }} {{ CROSS_CFLAGS }} {{ CROSS_INCLUDES }} \
|
|
-c {{ BUILD_DIR }}-{{ module }}/module_host.c \
|
|
-o {{ BUILD_DIR }}-{{ module }}/system.o
|
|
|
|
[private]
|
|
build-wasm-host-linux module:
|
|
{{ LINUX_CC }} {{ LINUX_CFLAGS }} {{ LINUX_INCLUDES }} \
|
|
-c {{ BUILD_DIR }}-{{ module }}/module_host.c \
|
|
-o {{ BUILD_DIR }}-{{ module }}/system.o
|
|
|
|
[private]
|
|
build-wasm-host-linux-baremetal module:
|
|
{{ CROSS_CC }} {{ LINUX_BAREMETAL_CFLAGS }} {{ LINUX_BAREMETAL_INCLUDES }} \
|
|
-c {{ BUILD_DIR }}-{{ module }}/module_host.c \
|
|
-o {{ BUILD_DIR }}-{{ module }}/system.o
|
|
|
|
[private]
|
|
build-wasm-host-dispatch module target="fail":
|
|
#!/usr/bin/env sh
|
|
if [ "{{ target }}" = "fail" ]; then
|
|
just build-wasm-host-fail "{{ module }}"
|
|
elif [ "{{ target }}" = "linux" ]; then
|
|
just build-wasm-host-linux "{{ module }}"
|
|
elif [ "{{ target }}" = "linux-baremetal" ]; then
|
|
just build-wasm-host-linux-baremetal "{{ module }}"
|
|
else
|
|
echo "unknown target: {{ target }}" >&2
|
|
exit 1
|
|
fi
|
|
|
|
[doc("Compile C-Host: The host uses WAMR to load the AOT module")]
|
|
[group("build-host")]
|
|
build-wasm-host module target="fail": (build-wasm-aot-array module) && (build-wasm-host-dispatch module target)
|
|
cp targets/wasm-host/{{ target }}.c {{ BUILD_DIR }}-{{ module }}/module_host.c
|
|
sed -i \
|
|
-e "s/__WASM_ARRAY_FILE__/wasm_module_array.c/g" \
|
|
-e "s/__WASM_ARRAY__/build_{{ module }}_wasm_module_aot/g" \
|
|
-e "s/__WASM_ARRAY_LEN__/build_{{ module }}_wasm_module_aot_len/g" \
|
|
{{ BUILD_DIR }}-{{ module }}/module_host.c
|
|
|
|
[private]
|
|
build-system-startup-fail module:
|
|
{{ CROSS_CC }} targets/startup.s {{ CROSS_CFLAGS }} -c -o {{ BUILD_DIR }}-{{ module }}/startup.o
|
|
|
|
[doc("Compile bootloader")]
|
|
[group("build-host")]
|
|
build-system-startup module target="fail":
|
|
#!/usr/bin/env sh
|
|
if [ "{{ target }}" = "fail" ]; then
|
|
just build-system-startup-fail "{{ module }}"
|
|
else
|
|
echo "{{ target }} doesn't need bootloader"
|
|
fi
|
|
|
|
[private]
|
|
build-system-syscalls-fail module:
|
|
{{ CROSS_CC }} targets/syscalls.c {{ CROSS_CFLAGS }} -c -o {{ BUILD_DIR }}-{{ module }}/syscalls.o
|
|
|
|
[private]
|
|
build-system-syscalls-linux-baremetal module:
|
|
{{ CROSS_CC }} targets/syscalls.c {{ LINUX_BAREMETAL_CFLAGS }} -c -o {{ BUILD_DIR }}-{{ module }}/syscalls.o
|
|
|
|
[doc("Compile newlib syscall stubs")]
|
|
[group("build-host")]
|
|
build-system-syscalls module target="fail":
|
|
#!/usr/bin/env sh
|
|
if [ "{{ target }}" = "fail" ]; then
|
|
just build-system-syscalls-fail "{{ module }}"
|
|
elif [ "{{ target }}" = "linux-baremetal" ]; then
|
|
just build-system-syscalls-linux-baremetal "{{ module }}"
|
|
else
|
|
echo "{{ target }} doesn't require syscall stubs"
|
|
fi
|
|
|
|
[private]
|
|
link-system-fail module:
|
|
{{ CROSS_CC }} \
|
|
-Wl,-T targets/linker.ld \
|
|
{{ BUILD_DIR }}-{{ module }}/system.o \
|
|
{{ BUILD_DIR }}-{{ module }}/startup.o \
|
|
{{ BUILD_DIR }}-{{ module }}/syscalls.o \
|
|
{{ CROSS_LDFLAGS }} \
|
|
-o {{ BUILD_DIR }}-{{ module }}/system.elf
|
|
|
|
[private]
|
|
link-system-linux module:
|
|
{{ LINUX_CC }} \
|
|
{{ BUILD_DIR }}-{{ module }}/system.o \
|
|
{{ LINUX_LDFLAGS }} \
|
|
-o {{ BUILD_DIR }}-{{ module }}/system.elf
|
|
|
|
[private]
|
|
link-system-linux-baremetal module:
|
|
{{ CROSS_CC }} \
|
|
{{ BUILD_DIR }}-{{ module }}/system.o \
|
|
{{ BUILD_DIR }}-{{ module }}/syscalls.o \
|
|
{{ LINUX_BAREMETAL_LDFLAGS }} \
|
|
-o {{ BUILD_DIR }}-{{ module }}/system.elf
|
|
|
|
[doc("Link C-Host, syscall stubs and bootloader")]
|
|
[group("build-host")]
|
|
link-system module target="fail": (build-wasm-host module target) (build-system-syscalls module target) (build-system-startup module target)
|
|
#!/usr/bin/env sh
|
|
if [ "{{ target }}" = "fail" ]; then
|
|
just link-system-fail "{{ module }}"
|
|
elif [ "{{ target }}" = "linux" ]; then
|
|
just link-system-linux "{{ module }}"
|
|
elif [ "{{ target }}" = "linux-baremetal" ]; then
|
|
just link-system-linux-baremetal "{{ module }}"
|
|
else
|
|
echo "unknown target: {{ target }}" >&2
|
|
exit 1
|
|
fi
|
|
|
|
[doc("Create bootdisk")]
|
|
[group("build-host")]
|
|
build-iso module target="fail": (link-system module target)
|
|
mkdir -p {{ BUILD_DIR }}-{{ module }}/grub/boot/grub
|
|
cp targets/grub.cfg {{ BUILD_DIR }}-{{ module }}/grub/boot/grub/
|
|
cp {{ BUILD_DIR }}-{{ module }}/system.elf {{ BUILD_DIR }}-{{ module }}/grub/boot/
|
|
grub-mkrescue -o {{ BUILD_DIR }}-{{ module }}/system.iso {{ BUILD_DIR }}-{{ module }}/grub
|
|
|
|
# =================================================================================================================== #
|
|
# MySQL recipes
|
|
# =================================================================================================================== #
|
|
|
|
[doc("Start MySQL container to receive FAIL* trace/campaign results")]
|
|
[group("fail-db")]
|
|
start-db:
|
|
docker run -d \
|
|
--name fail-db \
|
|
-e MYSQL_ROOT_PASSWORD=fail \
|
|
-e MYSQL_USER=fail \
|
|
-e MYSQL_PASSWORD=fail \
|
|
-e MYSQL_DATABASE=fail \
|
|
-p 3306:3306 \
|
|
mysql
|
|
|
|
[doc("Connect to MySQL database using DBeaver")]
|
|
[group("fail-db")]
|
|
connect-db:
|
|
dbeaver -con "name=fail|driver=mysql|host=localhost|port=3306|database=fail|user=fail|password=fail"
|
|
|
|
[doc("Stop MySQL container")]
|
|
[group("fail-db")]
|
|
stop-db:
|
|
docker stop fail-db
|
|
|
|
[doc("Remove MySQL container")]
|
|
[group("fail-db")]
|
|
remove-db:
|
|
docker container rm fail-db
|
|
|
|
# =================================================================================================================== #
|
|
# FAIL* recipes
|
|
# =================================================================================================================== #
|
|
|
|
BOCHS_RUNNER := "bochs-experiment-runner.py"
|
|
FAIL_TRACE := "fail-x86-tracing"
|
|
FAIL_DUMP := "dump-trace"
|
|
FAIL_IMPORT := "import-trace"
|
|
FAIL_PRUNE := "prune-trace"
|
|
FAIL_SERVER := "generic-experiment-server"
|
|
FAIL_INJECT := "generic-experiment-client"
|
|
RESULT_BROWSER := "resultbrowser.py"
|
|
|
|
[doc("Trace a golden run using FAIL*")]
|
|
[group("fail")]
|
|
trace module:
|
|
{{ BOCHS_RUNNER }} \
|
|
-V {{ FAIL_SHARE }}/vgabios.bin \
|
|
-b {{ FAIL_SHARE }}/BIOS-bochs-latest \
|
|
-1 \
|
|
-f {{ FAIL_TRACE }} \
|
|
-e {{ BUILD_DIR }}-{{ module }}/system.elf \
|
|
-i {{ BUILD_DIR }}-{{ module }}/system.iso \
|
|
-- \
|
|
-Wf,--start-symbol=start_trace \
|
|
-Wf,--save-symbol=start_trace \
|
|
-Wf,--end-symbol=stop_trace \
|
|
-Wf,--state-file={{ BUILD_DIR }}-{{ module }}/state \
|
|
-Wf,--trace-file={{ BUILD_DIR }}-{{ module }}/trace.pb \
|
|
-Wf,--elf-file={{ BUILD_DIR }}-{{ module }}/system.elf
|
|
@echo "Next step: \"just import {{ module }}\""
|
|
|
|
# [doc("Dump a FAIL* golden run trace")]
|
|
# [group("fail")]
|
|
# dump module:
|
|
# {{ FAIL_DUMP }} {{ BUILD_DIR }}-{{ module }}/trace.pb
|
|
|
|
[doc("Import a FAIL* golden run trace")]
|
|
[group("fail")]
|
|
import module:
|
|
{{ FAIL_IMPORT }} --database-option-file ./db.conf -t {{ BUILD_DIR }}-{{ module }}/trace.pb \
|
|
-i MemoryImporter \
|
|
-e {{ BUILD_DIR }}-{{ module }}/system.elf -v {{ module }} -b mem
|
|
{{ FAIL_IMPORT }} --database-option-file ./db.conf -t {{ BUILD_DIR }}-{{ module }}/trace.pb \
|
|
-i RegisterImporter \
|
|
-e {{ BUILD_DIR }}-{{ module }}/system.elf -v {{ module }} -b regs --flags
|
|
{{ FAIL_IMPORT }} --database-option-file ./db.conf -t {{ BUILD_DIR }}-{{ module }}/trace.pb \
|
|
-i RegisterImporter \
|
|
-e {{ BUILD_DIR }}-{{ module }}/system.elf -v {{ module }} -b ip --no-gp --ip
|
|
|
|
{{ FAIL_IMPORT }} --database-option-file ./db.conf -t {{ BUILD_DIR }}-{{ module }}/trace.pb \
|
|
-i ElfImporter --objdump objdump \
|
|
-e {{ BUILD_DIR }}-{{ module }}/system.elf -v {{ module }} -b ip
|
|
{{ FAIL_IMPORT }} --database-option-file ./db.conf -t {{ BUILD_DIR }}-{{ module }}/trace.pb \
|
|
-i ElfImporter --objdump objdump \
|
|
-e {{ BUILD_DIR }}-{{ module }}/system.elf -v {{ module }} -b mem
|
|
{{ FAIL_IMPORT }} --database-option-file ./db.conf -t {{ BUILD_DIR }}-{{ module }}/trace.pb \
|
|
-i ElfImporter --objdump objdump \
|
|
-e {{ BUILD_DIR }}-{{ module }}/system.elf -v {{ module }} -b regs
|
|
|
|
{{ FAIL_IMPORT }} --database-option-file ./db.conf -t {{ BUILD_DIR }}-{{ module }}/trace.pb \
|
|
-i ElfImporter --objdump objdump \
|
|
-e {{ BUILD_DIR }}-{{ module }}/system.elf -v {{ module }} -b ip --sources
|
|
{{ FAIL_IMPORT }} --database-option-file ./db.conf -t {{ BUILD_DIR }}-{{ module }}/trace.pb \
|
|
-i ElfImporter --objdump objdump \
|
|
-e {{ BUILD_DIR }}-{{ module }}/system.elf -v {{ module }} -b mem --sources
|
|
{{ FAIL_IMPORT }} --database-option-file ./db.conf -t {{ BUILD_DIR }}-{{ module }}/trace.pb \
|
|
-i ElfImporter --objdump objdump \
|
|
-e {{ BUILD_DIR }}-{{ module }}/system.elf -v {{ module }} -b regs --sources
|
|
|
|
{{ FAIL_PRUNE }} --database-option-file ./db.conf -v {{ module }} -b %% --overwrite
|
|
@echo "Next step: \"just server {{ module }}\""
|
|
|
|
[doc("Start the FAIL* campaign server")]
|
|
[group("fail")]
|
|
server module:
|
|
{{ FAIL_SERVER }} --database-option-file ./db.conf -v {{ module }} -b % --inject-single-bit --inject-registers &
|
|
@echo "Next step: \"just client {{ module }}\""
|
|
|
|
[doc("Stop the FAIL* campaign server")]
|
|
[group("fail")]
|
|
stop-server:
|
|
pkill -f {{ FAIL_SERVER }}
|
|
|
|
[doc("Start a FAIL* campaign client")]
|
|
[group("fail")]
|
|
client module:
|
|
{{ BOCHS_RUNNER }} \
|
|
-V {{ FAIL_SHARE }}/vgabios.bin \
|
|
-b {{ FAIL_SHARE }}/BIOS-bochs-latest \
|
|
-f {{ FAIL_INJECT }} \
|
|
-e {{ BUILD_DIR }}-{{ module }}/system.elf \
|
|
-i {{ BUILD_DIR }}-{{ module }}/system.iso \
|
|
-j {{ num_cpus() }} \
|
|
-- \
|
|
-Wf,--state-dir={{ BUILD_DIR }}-{{ module }}/state \
|
|
-Wf,--trap \
|
|
-Wf,--timeout=500000 \
|
|
-Wf,--ok-marker=ok_marker \
|
|
-Wf,--fail-marker=fail_marker \
|
|
> /dev/null
|
|
@echo "Next step: \"just result {{ module }}\" or \"just resultbrowser\""
|
|
|
|
[doc("Query FAIL* marker statistics from the database")]
|
|
[group("fail")]
|
|
result module:
|
|
@echo "select variant, benchmark, resulttype, sum(t.time2 - t.time1 + 1) as faults \
|
|
FROM variant v \
|
|
JOIN trace t ON v.id = t.variant_id \
|
|
JOIN fspgroup g ON g.variant_id = t.variant_id AND g.instr2 = t.instr2 AND g.data_address = t.data_address \
|
|
JOIN result_GenericExperimentMessage r ON r.pilot_id = g.pilot_id \
|
|
JOIN fsppilot p ON r.pilot_id = p.id \
|
|
WHERE v.variant = \"{{ module }}\" \
|
|
GROUP BY v.id, resulttype \
|
|
ORDER BY variant, benchmark, resulttype;" | mariadb --defaults-file=./db.conf -t
|
|
|
|
[doc("Start the FAIL* resultbrowser")]
|
|
[group("fail")]
|
|
resultbrowser:
|
|
{{ RESULT_BROWSER }} -c ./db.conf --host=0.0.0.0 --port=5000
|
|
|
|
# =================================================================================================================== #
|
|
# Debugging recipes
|
|
# =================================================================================================================== #
|
|
|
|
[doc("Run binary")]
|
|
[group("debug")]
|
|
run module:
|
|
{{ BUILD_DIR }}-{{ module }}/system.elf
|
|
|
|
[doc("Launch gdb")]
|
|
[group("debug")]
|
|
gdb module:
|
|
gdb --tui {{ BUILD_DIR }}-{{ module }}/system.elf
|
|
|
|
[doc("Launch radare2 at os_main")]
|
|
[group("debug")]
|
|
radare module:
|
|
radare2 -AA -c "s dbg.os_main; pdf" {{ BUILD_DIR }}-{{ module }}/system.elf
|