diff --git a/Makefile b/Makefile index cab860a..96a84b8 100644 --- a/Makefile +++ b/Makefile @@ -9,3 +9,9 @@ run-external: bochs-host: nix shell nixpkgs#bochs --command sh -c "bochs -q -f ./examples/arch/bochs/bochsrc-host.txt -q" + +qemu-host: + qemu-system-i386 -drive file=./examples/build-bochs/sum/system.iso,media=cdrom -boot d -m 32 -S -s + +gdb-host: + nix shell nixpkgs#gdb --command gdb ./examples/build-bochs/sum/system.elf -ex "set substitute-path build-bochs ./examples/build-bochs" -ex "target remote localhost:1234" -ex "break os_main" diff --git a/examples/Makefile b/examples/Makefile index 25c1a1e..b5fdbb5 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -1,17 +1,6 @@ ARCH ?= bochs - -BUILD_DIR := build-${ARCH} -FAIL_BIN ?= /home/fail/bin -FAIL_SERVER ?= ${FAIL_BIN}/generic-experiment-server -FAIL_TRACE ?= ${FAIL_BIN}/generic-tracing-client -FAIL_INJECT ?= ${FAIL_BIN}/generic-experiment-client -FAIL_DUMP ?= ${FAIL_BIN}/dump-trace -FAIL_IMPORT ?= ${FAIL_BIN}/import-trace --enable-sanitychecks -FAIL_PRUNE ?= ${FAIL_BIN}/prune-trace -BOCHS_RUNNER ?= ${FAIL_BIN}/bochs-experiment-runner.py -RESULT_BROWSER ?= ${FAIL_BIN}/resultbrowser.py - -EXPERIMENTS := $(patsubst %.c,%,$(shell echo *.c)) +BUILD_DIR := build-${ARCH} +EXPERIMENTS := $(patsubst %.c,%,$(shell echo *.c)) include arch/${ARCH}.mk @@ -25,42 +14,39 @@ help: @echo "Current Configuartion" @echo " ARCH=${ARCH}" - clean: - rm -f *.wasm - rm -f *.aot - rm -f *_wasm.c - rm -f *.d - rm -f *.o - rm -f embed/*_host.c - rm -f *_host.elf - rm -rf ${BUILD_DIR} + # rm -f *.wasm + # rm -f *.aot + # rm -f *_wasm.c + # rm -f *.d + # rm -f *.o + # rm -f embed/*_host.c + # rm -f *_host.elf + rm -rf ${BUILD_DIR}/* clean-%: rm -rf ${BUILD_DIR}/$(patsubst clean-%,%,$@) contrib/clean-db '${ARCH}/$(patsubst clean-%,%,$@)' - build-%: @echo "****************************************************************\n\ -* The next step is to trace a golden run. The golden run executes the\n\ -* system-under-test (SUT) within the emulator. A trace file is \n\ -* produced and saved as: ${BUILD_DIR}/main/trace.pb\n\ -*\n\ -* $ make trace-$(patsubst build-%,%,$@)\n\ -****************************************************************" - + * The next step is to trace a golden run. The golden run executes the\n \ + * system-under-test (SUT) within the emulator. A trace file is \n \ + * produced and saved as: ${BUILD_DIR}/main/trace.pb\n \ + *\n \ + * $ make trace-$(patsubst build-%,%,$@)\n \ + ****************************************************************" trace-%: @echo "****************************************************************\n\ -* The trace is now generated. It can be viewed with\n\ -*\n\ -* $ make dump-$(patsubst trace-%,%,$@)\n\ -*\n\ -* Next, we have to import the trace into the database\n\ -*\n\ -* $ make import-$(patsubst trace-%,%,$@)\n\ -****************************************************************" + * The trace is now generated. It can be viewed with\n \ + *\n \ + * $ make dump-$(patsubst trace-%,%,$@)\n \ + *\n \ + * Next, we have to import the trace into the database\n \ + *\n \ + * $ make import-$(patsubst trace-%,%,$@)\n \ + ****************************************************************" dump-%: ${BUILD_DIR}/%/trace.pb ${FAIL_DUMP} $(shell dirname $<)/trace.pb @@ -75,17 +61,17 @@ ${HOME}/.my.cnf: import-%: import-arch-% @echo "****************************************************************\n\ -* The golden run sits now within the MySQL database. If you are interested,\n\ -* use the 'mysql' command to inspect the curent state of the DB. The tables\n\ -* trace, fsppilot, and fspgroup are of special interest.\n\ -*\n\ -* Next, we have to run the campaign sever and the injection client\n\ -*\n\ -* $ make server-$(patsubst import-%,%,$@) &\n\ -* $ make client-$(patsubst import-%,%,$@) \n\n\ -* Afterwards, the results can be viewd with\n\ -* $ make result-$(subst import-,,$@)\n\ -****************************************************************" + * The golden run sits now within the MySQL database. If you are interested,\n \ + * use the 'mysql' command to inspect the curent state of the DB. The tables\n \ + * trace, fsppilot, and fspgroup are of special interest.\n \ + *\n \ + * Next, we have to run the campaign sever and the injection client\n \ + *\n \ + * $ make server-$(patsubst import-%,%,$@) &\n \ + * $ make client-$(patsubst import-%,%,$@) \n\n \ + * Afterwards, the results can be viewd with\n \ + * $ make result-$(subst import-,,$@)\n \ + ****************************************************************" server-%: ${FAIL_SERVER} -v ${ARCH}/$(subst server-,,$@) -b % @@ -94,16 +80,15 @@ result-%: @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 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 = \"${ARCH}/$(patsubst result-%,%,$@)\"\ + WHERE v.variant = \"${ARCH}/$(patsubst result-%,%,$@)\" \ GROUP BY v.id, resulttype \ ORDER BY variant, benchmark, resulttype;" |mysql -t resultbrowser: ${RESULT_BROWSER} --host=0.0.0.0 --port=5000 - # Do never remove implicitly generated stuff .SECONDARY: diff --git a/examples/arch/bochs.mk b/examples/arch/bochs.mk index 041045f..360f295 100644 --- a/examples/arch/bochs.mk +++ b/examples/arch/bochs.mk @@ -1,5 +1,9 @@ -# C -> WASM WASI_ROOT := /opt/wasi-sdk +WAMR := /opt/wamr + +################################################################ +# C -> WASM + WASI_CC := ${WASI_ROOT}/bin/clang WASI_CFLAGS := \ --target=wasm32 \ @@ -14,67 +18,6 @@ WASI_CFLAGS := \ -Wl,--export=__heap_base \ -Wl,--export=__data_end -# WASM -> Baremetal -WAMR := /opt/wamr - -WAMRC := /opt/wamr-wamrc/wamrc -WAMRCFLAGS := \ - --target=i386 \ - --cpu=generic -XXD := busybox xxd - -# NOTE: make build-sum: "error: bp cannot be used in ‘asm’ here" -# could remove "ebp" from the clobber list (ARCH_ASM_CLOBBER_ALL) or -# use the -fomit-frame-pointer flag to tell gcc it shouldn't rely on ebp for enter/leave... -CC := /opt/crosscompiler/bin/i686-elf-gcc -CFLAGS := \ - -I. \ - -O0 \ - -m32 \ - -ffunction-sections \ - -fomit-frame-pointer \ - -ggdb -IWASM_LIB := /opt/wamr-libiwasm # Baremetal -LDFLAGS = \ - -Wl,-T linker.ld \ - $^ \ - -Wl,--build-id=none \ - -static \ - -nostdlib \ - -m32 \ - -Wl,-rpath,${IWASM_LIB} \ - -L${IWASM_LIB} \ - -liwasm \ - -lc \ - -lgcc -INCL := \ - -I${WAMR}/core/iwasm/include \ - -I${WAMR}/core/shared/utils \ - -I${WAMR}/core/shared/platform/baremetal \ - -I/opt/crosscompiler/i686-elf/include - -CC_LINUX := gcc -CFLAGS_LINUX := \ - -I. \ - -O0 \ - -m32 \ - -ffunction-sections \ - -ggdb -IWASM_LIB_LINUX := /opt/wamr-libiwasm-linux -LDFLAGS_LINUX = \ - $^ \ - -m32 \ - -Wl,-rpath,${IWASM_LIB_LINUX} \ - -L${IWASM_LIB_LINUX} \ - -liwasm \ - -lm -INCL_LINUX := \ - -I${WAMR}/core/iwasm/include \ - -I${WAMR}/core/shared/utils \ - -I${WAMR}/core/shared/platform/linux - -################################################################ -# C -> WASM ${BUILD_DIR}/%/module.wasm: %.c mkdir -p $(shell dirname $@) ${WASI_CC} ${WASI_CFLAGS} $< -o $@ @@ -92,20 +35,58 @@ ${BUILD_DIR}/%/module.wasm: %.c ################################################################ # WASM -> AOT -> Loaded by Runtime (FAIL) + +WAMRC := /opt/wamr-wamrc/wamrc +WAMRCFLAGS := \ + --target=i386 \ + --cpu=generic + ${BUILD_DIR}/%/module.aot: ${BUILD_DIR}/%/module.wasm ${WAMRC} ${WAMRCFLAGS} -o $@ $< +XXD := busybox xxd + ${BUILD_DIR}/%/module_wasm.c: ${BUILD_DIR}/%/module.aot ${XXD} -i $< > $@ +# NOTE: make build-sum: "error: bp cannot be used in ‘asm’ here" +# could remove "ebp" from the clobber list (ARCH_ASM_CLOBBER_ALL) or +# use the -fomit-frame-pointer flag to tell gcc it shouldn't rely on ebp for enter/leave... +CC := /opt/crosscompiler/bin/i386-elf-gcc +CFLAGS := \ + -I. \ + -O0 \ + -m32 \ + -ffunction-sections \ + -ffreestanding \ + -fomit-frame-pointer \ + -ggdb +IWASM_LIB := /opt/wamr-libiwasm # Baremetal +LDFLAGS = \ + -Wl,-T linker.ld \ + $^ \ + -Wl,--build-id=none \ + -static \ + -nostdlib \ + -m32 \ + -L${IWASM_LIB} \ + -liwasm \ + -lc \ + -lgcc \ + -lm +INCL := \ + -I${WAMR}/core/iwasm/include \ + -I${WAMR}/core/shared/utils \ + -I${WAMR}/core/shared/platform/baremetal + ${BUILD_DIR}/%/system.o: ${BUILD_DIR}/%/module_wasm.c - cp embed/host.c ${BUILD_DIR}/$*/module_host.c + cp embed/host-fail.c ${BUILD_DIR}/$*/module_host-fail.c sed -i \ -e "s/__WASM_ARRAY_FILE__/module_wasm.c/g" \ -e "s/__WASM_ARRAY__/build_bochs_$*_module_aot/g" \ -e "s/__WASM_ARRAY_LEN__/build_bochs_$*_module_aot_len/g" \ - ${BUILD_DIR}/$*/module_host.c - ${CC} ${CFLAGS} ${INCL} -c ${BUILD_DIR}/$*/module_host.c -o $@ + ${BUILD_DIR}/$*/module_host-fail.c + ${CC} ${CFLAGS} ${INCL} -c ${BUILD_DIR}/$*/module_host-fail.c -o $@ ${BUILD_DIR}/startup.o: arch/bochs/startup.s ${CC} $< ${CFLAGS} -c -o $@ @@ -117,7 +98,30 @@ ${BUILD_DIR}/%/system.elf: ${BUILD_DIR}/%/system.o ${BUILD_DIR}/syscalls.o ${BUI ${CC} ${LDFLAGS} -o $@ ################################################################ -# WASM -> AOT -> Loaded by Runtime (Host/Linux) +# WASM -> AOT -> Loaded by Runtime (Host/Linux platform) + +CC_LINUX := gcc +CFLAGS_LINUX := \ + -I. \ + -O0 \ + -m32 \ + -ffunction-sections \ + -ggdb +IWASM_LIB_LINUX := /opt/wamr-libiwasm-linux +LDFLAGS_LINUX = \ + $^ \ + -Wl,--build-id=none \ + -static \ + -m32 \ + -Wl,-rpath,${IWASM_LIB_LINUX} \ + -L${IWASM_LIB_LINUX} \ + -liwasm \ + -lm +INCL_LINUX := \ + -I${WAMR}/core/iwasm/include \ + -I${WAMR}/core/shared/utils \ + -I${WAMR}/core/shared/platform/linux + ${BUILD_DIR}/%/system-linux.o: ${BUILD_DIR}/%/module_wasm.c cp embed/host-linux.c ${BUILD_DIR}/$*/module_host-linux.c sed -i \ @@ -131,7 +135,61 @@ ${BUILD_DIR}/%/system-linux.elf: ${BUILD_DIR}/%/system-linux.o ${CC_LINUX} ${LDFLAGS_LINUX} -o $@ ################################################################ -# Bochs +# WASM -> AOT -> Loaded by Runtime (Host/Baremetal platform) + +CC_BAREMETAL := /opt/crosscompiler/bin/i386-elf-gcc +CFLAGS_BAREMETAL := \ + -I. \ + -O0 \ + -m32 \ + -ffunction-sections \ + -ffreestanding \ + -ggdb +IWASM_LIB_BAREMETAL := /opt/wamr-libiwasm +LDFLAGS_BAREMETAL = \ + $^ \ + -Wl,--build-id=none \ + -static \ + -nostdlib \ + -m32 \ + -L${IWASM_LIB_BAREMETAL} \ + -liwasm \ + -lc \ + -lgcc \ + -lm \ + --entry main +# Trace where the memset symbol is actually coming from +# LDFLAGS_BAREMETAL += -Wl,-Map,$@.map -Wl,--trace-symbol=memset +INCL_BAREMETAL := \ + -I${WAMR}/core/iwasm/include \ + -I${WAMR}/core/shared/utils \ + -I${WAMR}/core/shared/platform/baremetal + +${BUILD_DIR}/%/system-baremetal.o: ${BUILD_DIR}/%/module_wasm.c + cp embed/host-baremetal.c ${BUILD_DIR}/$*/module_host-baremetal.c + sed -i \ + -e "s/__WASM_ARRAY_FILE__/module_wasm.c/g" \ + -e "s/__WASM_ARRAY__/build_bochs_$*_module_aot/g" \ + -e "s/__WASM_ARRAY_LEN__/build_bochs_$*_module_aot_len/g" \ + ${BUILD_DIR}/$*/module_host-baremetal.c + ${CC_BAREMETAL} ${CFLAGS_BAREMETAL} ${INCL_BAREMETAL} -c ${BUILD_DIR}/$*/module_host-baremetal.c -o $@ + +${BUILD_DIR}/%/system-baremetal.elf: ${BUILD_DIR}/%/system-baremetal.o ${BUILD_DIR}/syscalls.o + ${CC_BAREMETAL} ${LDFLAGS_BAREMETAL} -o $@ + +################################################################ +# Fail/Bochs + +FAIL_BIN ?= /home/fail/bin +FAIL_SERVER ?= ${FAIL_BIN}/generic-experiment-server +FAIL_TRACE ?= ${FAIL_BIN}/generic-tracing-client +FAIL_INJECT ?= ${FAIL_BIN}/generic-experiment-client +FAIL_DUMP ?= ${FAIL_BIN}/dump-trace +FAIL_IMPORT ?= ${FAIL_BIN}/import-trace --enable-sanitychecks +FAIL_PRUNE ?= ${FAIL_BIN}/prune-trace +BOCHS_RUNNER ?= ${FAIL_BIN}/bochs-experiment-runner.py +RESULT_BROWSER ?= ${FAIL_BIN}/resultbrowser.py + ${BUILD_DIR}/%/system.iso: ${BUILD_DIR}/%/system.elf rm -rf $(shell dirname $<)/grub mkdir -p $(shell dirname $<)/grub/boot/grub @@ -217,6 +275,20 @@ linux-run-$1: ${BUILD_DIR}/$1/system-linux.elf linux-gdb-$1: ${BUILD_DIR}/$1/system-linux.elf gdb --tui ${BUILD_DIR}/$1/system-linux.elf +linux-objdump-$1: + objdump --disassemble --disassembler-options intel --disassembler-color=off --source ${BUILD_DIR}/$1/system-linux.elf | less + +baremetal-build-$1: ${BUILD_DIR}/$1/system-baremetal.elf + +baremetal-run-$1: ${BUILD_DIR}/$1/system-baremetal.elf + ${BUILD_DIR}/$1/system-baremetal.elf + +baremetal-gdb-$1: ${BUILD_DIR}/$1/system-baremetal.elf + gdb --tui -ex "set substitute-path /wamrlib ${WAMR}" ${BUILD_DIR}/$1/system-baremetal.elf + +baremetal-objdump-$1: + objdump --disassemble --disassembler-options intel --disassembler-color=off --source ${BUILD_DIR}/$1/system-baremetal.elf | less + bochs-run-$1: ${BUILD_DIR}/$1/system.iso bochs -q -f arch/bochs/bochsrc-docker.txt diff --git a/examples/embed/host-baremetal.c b/examples/embed/host-baremetal.c new file mode 100644 index 0000000..06b8b93 --- /dev/null +++ b/examples/embed/host-baremetal.c @@ -0,0 +1,85 @@ +// https://github.com/bytecodealliance/wasm-micro-runtime/blob/WAMR-2.4.4/doc/embed_wamr.md + +#include "lib.c" + +#include "bh_platform.h" +#include "wasm_export.h" + +#include "__WASM_ARRAY_FILE__" + +#define STACK_SIZE (4 * 1024) +#define HEAP_SIZE STACK_SIZE +#define RUNTIME_POOL_SIZE (4 * STACK_SIZE) + +// TODO: Set this up so the lsp actually finds the includes... + +// MAIN() { +int main(int argc, char *argv[]) { + char error_buf[128]; + wasm_module_t module; + wasm_module_inst_t module_inst; + wasm_function_inst_t func; + wasm_exec_env_t exec_env; + + /* initialize the wasm runtime */ + static char global_heap_buf[RUNTIME_POOL_SIZE]; + static RuntimeInitArgs init_args; + memset(&init_args, 0, sizeof(RuntimeInitArgs)); + + // init_args.mem_alloc_type = Alloc_With_System_Allocator; + init_args.mem_alloc_type = Alloc_With_Pool; + init_args.mem_alloc_option.pool.heap_buf = global_heap_buf; + init_args.mem_alloc_option.pool.heap_size = sizeof(global_heap_buf); + init_args.max_thread_num = 1; + if (!wasm_runtime_full_init(&init_args)) { + return 1; + } + + /* parse the WASM file from buffer and create a WASM module */ + module = wasm_runtime_load(__WASM_ARRAY__, __WASM_ARRAY_LEN__, error_buf, + sizeof(error_buf)); + + if (!module) { + return 1; + } + + /* create an instance of the WASM module (WASM linear memory is ready) */ + module_inst = wasm_runtime_instantiate(module, STACK_SIZE, HEAP_SIZE, + error_buf, sizeof(error_buf)); + + if (!module_inst) { + return 1; + } + + /* lookup a WASM function by its name, the function signature can NULL here */ + func = wasm_runtime_lookup_function(module_inst, "wasm_module"); + + /* create an execution environment to execute arbitrary WASM functions */ + exec_env = wasm_runtime_create_exec_env(module_inst, STACK_SIZE); + + /* arguments are always transferred in 32-bit element */ + uint32_t args[1]; + + /* call an arbitrary WASM function */ + // MARKER(start_trace); + if (!wasm_runtime_call_wasm(exec_env, func, 0, args)) { + /* function wasn't called correctly */ + } + // MARKER(stop_trace); + // + uint32_t result = args[0]; + + wasm_runtime_destroy_exec_env(exec_env); + wasm_runtime_deinstantiate(module_inst); + wasm_runtime_unload(module); + wasm_runtime_destroy(); + + /* the return value is stored in args[0] */ + if (result == 100) { + // MARKER(ok_marker); + return 0; + } else { + // MARKER(fail_marker); + return 1; + } +} diff --git a/examples/embed/host.c b/examples/embed/host-fail.c similarity index 99% rename from examples/embed/host.c rename to examples/embed/host-fail.c index 037bf29..fd9d915 100644 --- a/examples/embed/host.c +++ b/examples/embed/host-fail.c @@ -59,7 +59,7 @@ MAIN() { exec_env = wasm_runtime_create_exec_env(module_inst, STACK_SIZE); /* arguments are always transferred in 32-bit element */ - uint32 args[1]; + uint32_t args[1]; /* call an arbitrary WASM function */ MARKER(start_trace); diff --git a/examples/embed/host-linux.c b/examples/embed/host-linux.c index c463187..6f3bb45 100644 --- a/examples/embed/host-linux.c +++ b/examples/embed/host-linux.c @@ -61,7 +61,7 @@ int main(int argc, char *argv[]) { exec_env = wasm_runtime_create_exec_env(module_inst, STACK_SIZE); /* arguments are always transferred in 32-bit element */ - uint32 args[1]; + uint32_t args[1]; /* call an arbitrary WASM function */ // MARKER(start_trace);