Draft wamr modifications + host program structure sections
This commit is contained in:
@@ -6,79 +6,4 @@
|
||||
|
||||
\chapter{Experiment Setup}\label{ch:experimentsetup}
|
||||
|
||||
\section{Execution Environment}\label{sec:executionenvironment}
|
||||
|
||||
To keep the experiment setup as simple as possible, experiments are executed in a bare-metal environment without any operating system.
|
||||
This has the advantage of avoiding some sources of possible non-determinism (caused, e.g., by scheduling or interrupts) during fault injection.
|
||||
It also prevents any operating system code from being targeted by the \Gls{fi} framework.
|
||||
While a suitable and correctly configured statically linked real-time operating system inside a controlled, emulated environment is not prone to those issues, running experiments bare-metal excludes this category of possible problems entirely.
|
||||
|
||||
Instead, experiments are cross-compiled to freestanding executables using \code{i386-elf-gcc} with Newlib\footnote{\url[2026-08-12]{https://sourceware.org/newlib/}} libc.
|
||||
To make Newlib work inside a bare-metal environment, certain system calls must be provided by the platform, although not all of them need to be functional\footnote{\url[2026-08-12]{https://sourceware.org/newlib/libgloss.html#Libraries-1}}:
|
||||
\begin{itemize}
|
||||
\item \code{sbrk()} is required for Newlib's \code{malloc()}, \code{calloc()} and \code{realloc()} memory-management functions. Although \Gls{wamr} uses its own memory allocator implementation (see \autoref{sec:wasmhostprogram}), \Gls{wasm} targets may still require a functional \code{sbrk()} if \Gls{wamr}'s \code{snprintf}/\code{vsnprintf} are used, depending on the format string.
|
||||
\item \code{read()}, \code{write()}, \code{close()}, \code{fstat()} and \code{isatty()} stubs are required for \Gls{wamr} targets. Since no filesystem or console exists in the execution environment, they do not need to be functional.
|
||||
\item \code{lseek()} is required for C and \Gls{wamr} targets. A stub suffices for the same reason as above.
|
||||
\item \code{\_exit()}, \code{kill()} and \code{getpid()} are required for \Gls{wamr} targets. Implementations can be omitted, as the execution environment does not use processes.
|
||||
\end{itemize}
|
||||
|
||||
For experiment execution, the executables are packed into Multiboot\footnote{\url[2026-07-13]{https://www.gnu.org/software/grub/manual/multiboot/multiboot.html}}-compatible disk images with GNU GRUB\footnote{\url[2026-08-12]{https://www.gnu.org/software/grub/}} embedded via \code{grub-mkrescue} and executed in \Gls{bochs} via \Gls{fail}.
|
||||
|
||||
\section{\Gls{wamr} Modifications}\label{sec:wamrmodifications}
|
||||
\begin{itemize}
|
||||
\item WAMR baremetal platform
|
||||
\item WAMR exception handler marker?
|
||||
\end{itemize}
|
||||
|
||||
\section{Wasm Host Program}\label{sec:wasmhostprogram}
|
||||
\begin{itemize}
|
||||
\item WAMR setup
|
||||
\item WAMR memory allocators
|
||||
\item Calling \code{FAIL\_MARKER}s (native functions)
|
||||
\end{itemize}
|
||||
|
||||
\section{Experiment Variants}\label{sec:experimenttypes}
|
||||
\begin{itemize}
|
||||
\item C only
|
||||
\item WAMR AOT
|
||||
\item WAMR interpreter
|
||||
\end{itemize}
|
||||
|
||||
\section{Controlling What Gets Injected/Memory Isolation}\label{sec:controllingmemoryisolation}
|
||||
\begin{itemize}
|
||||
\item How can the WAMR allocators be used to control what gets injected? They cannot. --catch-write-textsegment doesn't prevent injection, just writes of the regular program.
|
||||
\item --catch-write-textsegment (does NOT prevent injections into the textsegment!)
|
||||
\item --catch-outerspace
|
||||
\end{itemize}
|
||||
|
||||
\section{Controlling What Data Gets Extracted From The Experiments}
|
||||
\begin{itemize}
|
||||
\item What queries are run?
|
||||
\item How are the equivalence classes expanded?
|
||||
\item What/How is the data filtered (e.g., to exclude WAMR's native call chain)?
|
||||
\end{itemize}
|
||||
|
||||
\section{Missing FAIL\_MARKERs for AOT experiments}
|
||||
\begin{itemize}
|
||||
\item AOT Addressauflösung/Def-Use chain theory
|
||||
\item Somehow caught by --catch-write-textsegment or --catch-outerspace because stuff was linked to .text?
|
||||
\item Optimization theory
|
||||
\begin{itemize}
|
||||
\item Does the target program contain the expected instructions?
|
||||
\item Does FAIL* treat the variables as not live? (volatile, fail\_stop\_trace(sum))
|
||||
\item Trying more complex programs, as -O0 always writes intermediate results to memory
|
||||
\item Swap fail\_marker\_positive and fail\_marker\_negative
|
||||
\end{itemize}
|
||||
\item Does the pruner clear those injections for some reason?
|
||||
\item Does the disassembler not disassemble the .text subsections?
|
||||
\item Is the TracingPlugin broken? (GDB -> No, but FAIL* doesn't trace register accesses)
|
||||
\item Solution: Gap in the .elf symbol space (addresses that are not covered by some symbol). FAIL needs this to disassemble the Wasm AOT code to find the register accesses. FAIL also needs to find this AOT code, so it can't be relocated -> Needs --xip
|
||||
\end{itemize}
|
||||
|
||||
\section{Target Programs}
|
||||
\begin{itemize}
|
||||
\item Toy examples
|
||||
\item TacleBench~\autocite{TACLeBench,seidlerTACLeBenchWasmConverter2026}
|
||||
\end{itemize}
|
||||
|
||||
\end{document}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
%! TeX program = lualatex
|
||||
%! TeX root = ../../thesis.tex
|
||||
\documentclass[../../thesis.tex]{subfiles}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\section{Execution Environment}\label{sec:executionenvironment}
|
||||
|
||||
To keep the experiment setup as simple as possible, experiments are executed in a bare-metal environment without any operating system.
|
||||
This has the advantage of avoiding some sources of possible non-determinism (caused, e.g., by scheduling or interrupts) during fault injection.
|
||||
It also prevents any operating system code from being targeted by the \Gls{fi} framework.
|
||||
While a suitable and correctly configured statically linked real-time operating system inside a controlled, emulated environment is not prone to those issues, running experiments bare-metal excludes this category of possible problems entirely.
|
||||
|
||||
Instead, experiments are cross-compiled to freestanding executables using \code{i386-elf-gcc} with Newlib\footnote{\url[2026-08-12]{https://sourceware.org/newlib/}} libc.
|
||||
To make Newlib work inside a bare-metal environment, certain system calls must be provided by the platform, although not all of them need to be functional\footnote{\url[2026-08-12]{https://sourceware.org/newlib/libgloss.html\#Libraries-1}}:
|
||||
\begin{itemize}
|
||||
\item \code{sbrk()} is required for Newlib's \code{malloc()}, \code{calloc()} and \code{realloc()} memory-management functions. Although \Gls{wamr} uses its own memory allocator implementation (see \autoref{sec:wasmhostprogram}), \Gls{wasm} targets may still require a functional \code{sbrk()} if \Gls{wamr}'s \code{snprintf}/\code{vsnprintf} are used, depending on the format string.
|
||||
\item \code{read()}, \code{write()}, \code{close()}, \code{fstat()} and \code{isatty()} stubs are required for \Gls{wamr} targets. Since no filesystem or console exists in the execution environment, they do not need to be functional.
|
||||
\item \code{lseek()} is required for C and \Gls{wamr} targets. A stub suffices for the same reason as above.
|
||||
\item \code{\_exit()}, \code{kill()} and \code{getpid()} are required for \Gls{wamr} targets. Implementations can be omitted, as the execution environment does not use processes.
|
||||
\end{itemize}
|
||||
|
||||
For experiment execution, the executables are packed into Multiboot\footnote{\url[2026-07-13]{https://www.gnu.org/software/grub/manual/multiboot/multiboot.html}}-compatible disk images with GNU GRUB\footnote{\url[2026-08-12]{https://www.gnu.org/software/grub/}} embedded via \code{grub-mkrescue} and executed in \Gls{bochs} via \Gls{fail}.
|
||||
|
||||
\end{document}
|
||||
@@ -0,0 +1,43 @@
|
||||
%! TeX program = lualatex
|
||||
%! TeX root = ../../thesis.tex
|
||||
\documentclass[../../thesis.tex]{subfiles}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\section{\Gls{wamr} Modifications}\label{sec:wamrmodifications}
|
||||
|
||||
The experiments use a slightly modified version of \Gls{wamr} based on release 2.4.4\footnote{\url[2026-09-11]{https://github.com/wasm-micro-runtime/wasm-micro-runtime/releases/tag/WAMR-2.4.4}}.
|
||||
The modifications provide a platform port for the bare-metal execution environment described in \autoref{sec:executionenvironment} and an explicit marker call during runtime exceptions.
|
||||
|
||||
\subsection{Bare-Metal Platform}\label{ssec:wamrbaremetal}
|
||||
|
||||
\Gls{wamr} implements platform-specific details separately from the runtime inside its platform abstractions.
|
||||
The added \code{baremetal} platform only provides the subset of this layer that is required by the experiments.
|
||||
It is selected through \code{WAMR\_BUILD\_PLATFORM=baremetal} and compiled for 32-bit x86 using a freestanding cross-compiler.
|
||||
The build enables the classic interpreter and \Gls{aot} execution, while disabling the fast interpreter, the \Glspl{jit}, and WASI support.
|
||||
The modifications also remove the mandatory CMake thread-library lookup and disables the compiler option \code{-mindirect-branch-register}\todo{Option was disabled because gcc 5.4 didn't support it, now I'm using a newer cross compiler}.
|
||||
|
||||
Since execution is single-threaded and no operating system is present, many platform functions are stubs.
|
||||
Platform initialization and mutex operations report success without performing any work, console output is discarded, and time queries return zero.
|
||||
The system allocation functions \code{os\_malloc} and \code{os\_realloc} return \code{NULL}.
|
||||
Instead, the host initializes \Gls{wamr} with a supplied memory pool or custom allocation callbacks, as described later in \autoref{sssec:wamrmemoryallocation}.
|
||||
|
||||
\Gls{aot} experiment variants additionally require implementations of \code{os\_mmap} and \code{os\_mremap}, to allocate memory for the loaded module text.
|
||||
The platform provides these using a static \SI{2}{\mega\byte} buffer and a simple bump allocator (allocator with monotonically increasing offset into the reserved memory region).
|
||||
Remapping allocates a new region and copies the old one, without reclaiming any memory.
|
||||
Unmapping does not reclaim memory, and \code{os\_mprotect} reports success without changing access permissions.
|
||||
Thus, these functions only supply storage for the loader without implementing any other virtual-memory or memory protection related functionalities.
|
||||
|
||||
The \code{os\_mmap} buffer can optionally be placed in the linker section \code{.text.wamr\_mmap} by defining \code{WAMR\_MMAP\_IN\_TEXT}.
|
||||
The linker script fences this region with symbols so that faults can be attributed to this address range during \Gls{fail} experiment evaluation.
|
||||
|
||||
\subsection{Runtime Exception Marker}\label{ssec:wamrexceptionmarker}
|
||||
|
||||
To differentiate errors detected by the \Gls{wamr} runtime from other fault outcomes, a \code{fail\_marker\_group1} call is added to the \code{wasm\_set\_exception\_local} handler.
|
||||
Clearing an exception by passing \code{NULL} does not invoke the marker.
|
||||
This exception handler is utilized by both interpreted execution and \Gls{aot} execution, whose \code{aot\_set\_exception} forwards to \code{wasm\_set\_exception}.
|
||||
|
||||
To enable the \code{fail\_marker\_group1} outcome, the marker function symbol has to be registered with \Gls{fail}'s experiment runner.
|
||||
\Gls{fail} then installs a breakpoint listener at this function's address and aborts the injection run if it fires.
|
||||
|
||||
\end{document}
|
||||
@@ -0,0 +1,95 @@
|
||||
%! TeX program = lualatex
|
||||
%! TeX root = ../../thesis.tex
|
||||
\documentclass[../../thesis.tex]{subfiles}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\section{Workload Program Structure}\label{sec:workloadprogramstructure}
|
||||
|
||||
\subsection{Shared Traced Region}\label{ssec:sharedtracedregion}
|
||||
|
||||
All experiment variants (C, \Gls{aot} and interpreted) share the same traced region that contains the actual benchmarked workload.
|
||||
It is structured into three parts, the benchmark initialization, its execution and the success condition.
|
||||
Initialization and success condition lie outside the traced region (see \autoref{lst:workloadstructure}), so a workload under fault always starts with its intended initial state and its result is always evaluated correctly.
|
||||
|
||||
\begin{codeblock}[label=lst:workloadstructure]{Example of a shared workload.}{C++}
|
||||
\inputminted{cpp}{listings/workloadstructure.cpp}
|
||||
\end{codeblock}
|
||||
|
||||
The \code{EXPORT("fnct")} annotation expands to \code{\_\_attribute\_\_((export\_name("fnct")))}, a directive to the LLVM-based C-to-\Gls{wasm} compiler from the WASI SDK\footnote{\url[2026-09-11]{https://github.com/WebAssembly/wasi-sdk}} that controls the name of the exported \Gls{wasm} module.
|
||||
|
||||
Such a shared workload is then called from a variant-specific host program, as seen in the next two sections.
|
||||
|
||||
\subsection{Native Host}\label{ssec:nativehost}
|
||||
|
||||
The native host for C experiment variants (see \autoref{lst:nativehostprogram}) is the simplest of the two: it just calls the \code{wasm\_module} function described in \autoref{ssec:sharedtracedregion} and does not need to consider any runtime initialization.
|
||||
|
||||
For debugging purposes, the native C variant can also be compiled for Linux instead of \Gls{fail}'s bare-metal environment.
|
||||
The \code{MAIN} and \code{RET} macros expand according to the appropriate entry function signature required by the target platform.
|
||||
|
||||
\begin{codeblock}[label=lst:nativehostprogram]{Native workload host program.}{C++}
|
||||
\inputminted{cpp}{listings/nativehost.cpp}
|
||||
\end{codeblock}
|
||||
|
||||
\subsection{\Gls{wasm} Host and \Gls{wamr} Setup}\label{ssec:wasmhostandwamrsetup}
|
||||
|
||||
The host program for \Gls{wasm} experiment variants needs to do a lot of additional work compared to the native one, mainly concerning the initialization of the \Gls{wamr} runtime\footnote{Described here: \url[2026-09-11]{https://wasmruntime.com/en/tutorials/wamr\#34-step-4-c-embedding-integration}}.
|
||||
|
||||
\subsubsection{Runtime Initialization and Memory Allocation}\label{sssec:wamrmemoryallocation}
|
||||
|
||||
\Gls{wamr} supports two different allocators for the \Gls{wasm} runtime memory: \code{Alloc\_With\_Pool} and \code{Alloc\_With\_Allocator}.
|
||||
\code{Alloc\_With\_Pool} is the simplest one, as it only requires a memory pool and no custom allocator functions.
|
||||
\code{Alloc\_With\_Allocator} is slightly more involved, as it allows complete control over memory regions and allocation behavior by utilizing custom allocator functions.
|
||||
To use this allocator, \code{malloc}, \code{realloc} and \code{free} need to be implemented.
|
||||
In this thesis, a simple bump allocator is implemented, like the one used by \Gls{wamr} itself, described in \autoref{ssec:wamrbaremetal}
|
||||
|
||||
\begin{codeblock}[label=lst:wamrinit]{\Gls{wamr} initialization.}{C++}
|
||||
\inputminted{cpp}{listings/wamrinitialization.cpp}
|
||||
\end{codeblock}
|
||||
|
||||
The main advantage of the more complex \code{Alloc\_With\_Allocator} shows up when \Gls{wamr} is built with \code{WAMR\_BUILD\_ALLOC\_WITH\_USAGE=1}.
|
||||
This flag modifies the allocator function signatures to accept an additional \code{mem\_alloc\_usage\_t} argument, which can take the values \code{Alloc\_For\_Runtime} or \code{Alloc\_For\_LinearMemory}.
|
||||
Based on this value, memory allocations can be distributed across separate pools for \Gls{wamr} runtime memory and \Gls{wasm} linear memory, allowing a more in-depth experiment evaluation by attributing memory faults to different purposes or filtering faults originating from a specific memory pool entirely.
|
||||
|
||||
How to initialize the runtime with the desired configuration is shown in \autoref{lst:wamrinit}.
|
||||
|
||||
\subsubsection{Native Function Invocations}\label{sssec:wamrnativeinvocations}
|
||||
|
||||
\Gls{fail} markers are realized as breakpoint handlers in \Gls{fail}'s simulator backend, with the breakpoints registered to native marker function invocations.
|
||||
This presents a small problem when markers need to be called from within a workload that has been compiled to \Gls{wasm}, as those function invocations are no longer present as native instructions.
|
||||
|
||||
\begin{codeblock}[label=lst:wamrnativefunctions]{\Gls{wamr} native marker definitions.}{C++}
|
||||
\inputminted{cpp}{listings/wamrnativefunctions.cpp}
|
||||
\end{codeblock}
|
||||
|
||||
To circumvent this, \Gls{wamr}'s native function invocation mechanism can be used\footnote{Also described here: \url[2026-09-11]{https://wasmruntime.com/en/tutorials/wamr\#41-complete-example-logging-host-function}}: the breakpoint handlers are registered to native functions that are not compiled to \Gls{wasm} (see \autoref{lst:wamrnativefunctions}) but are registered to the \Gls{wamr} runtime instead (see \autoref{lst:wamrnativefunctionregistration}).
|
||||
|
||||
\begin{codeblock}[label=lst:wamrnativefunctionregistration]{\Gls{wamr} native function registration.}{C++}
|
||||
\inputminted{cpp}{listings/wamrnativefunctionregistration.cpp}
|
||||
\end{codeblock}
|
||||
|
||||
This registration populates a lookup table that maps the native function pointers to their names, so that \Gls{aot} programs can call \Gls{wamr}'s internal \code{aot\_invoke\_native} and interpreted programs can call \code{wasm\_interp\_call\_func\_native} to invoke those functions.
|
||||
This indirection happens implicitly, on the application level no special steps need to be taken, functions can be called by their registered names.
|
||||
|
||||
To be compatible with the native function registration mechanism, functions need to accept the \Gls{wasm} execution environment as an argument (see \autoref{lst:wamrnativefunctions}).
|
||||
|
||||
\subsubsection{\Gls{wasm} Module Instantiation and Execution}\label{sssec:wamrmoduleexecution}
|
||||
|
||||
To load the workload's \Gls{wasm} module and run it, a series of steps need to be executed:
|
||||
\begin{enumerate}
|
||||
\item Load the module (\code{wasm\_runtime\_load})
|
||||
\item Instantiate the module (\code{wasm\_runtime\_instantiate})
|
||||
\item Create a \Gls{wasm} execution environment (\code{wasm\_runtime\_create\_exec\_env})
|
||||
\item Find the exported entry function (\code{wasm\_runtime\_lookup\_function})
|
||||
\item Call the exported entry function (\code{wasm\_runtime\_call\_wasm})
|
||||
\end{enumerate}
|
||||
|
||||
In this thesis, compiled \Gls{wasm} modules are converted to C-style arrays using \code{xxd} and embedded into the program's source text.
|
||||
This way, file access can be avoided and the module is loaded by simply passing a pointer to the correct function.
|
||||
A simplified module call sequence is shown in \autoref{lst:wamrmodulecall}.
|
||||
|
||||
\begin{codeblock}[label=lst:wamrmodulecall]{Calling a \Gls{wasm} module from C.}{C++}
|
||||
\inputminted{cpp}{listings/wamrmodulecall.cpp}
|
||||
\end{codeblock}
|
||||
|
||||
\end{document}
|
||||
@@ -0,0 +1,15 @@
|
||||
%! TeX program = lualatex
|
||||
%! TeX root = ../../thesis.tex
|
||||
\documentclass[../../thesis.tex]{subfiles}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\section{Experiment Variants}\label{sec:experimenttypes}
|
||||
|
||||
\begin{itemize}
|
||||
\item C only
|
||||
\item WAMR AOT
|
||||
\item WAMR interpreter
|
||||
\end{itemize}
|
||||
|
||||
\end{document}
|
||||
@@ -0,0 +1,15 @@
|
||||
%! TeX program = lualatex
|
||||
%! TeX root = ../../thesis.tex
|
||||
\documentclass[../../thesis.tex]{subfiles}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\section{Controlling What Gets Injected/Memory Isolation}\label{sec:controllingmemoryisolation}
|
||||
|
||||
\begin{itemize}
|
||||
\item How can the WAMR allocators be used to control what gets injected? They cannot. --catch-write-textsegment doesn't prevent injection, just writes of the regular program.
|
||||
\item --catch-write-textsegment (does NOT prevent injections into the textsegment!)
|
||||
\item --catch-outerspace
|
||||
\end{itemize}
|
||||
|
||||
\end{document}
|
||||
@@ -0,0 +1,15 @@
|
||||
%! TeX program = lualatex
|
||||
%! TeX root = ../../thesis.tex
|
||||
\documentclass[../../thesis.tex]{subfiles}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\section{Controlling What Data Gets Extracted From The Experiments}
|
||||
|
||||
\begin{itemize}
|
||||
\item What queries are run?
|
||||
\item How are the equivalence classes expanded?
|
||||
\item What/How is the data filtered (e.g., to exclude WAMR's native call chain)?
|
||||
\end{itemize}
|
||||
|
||||
\end{document}
|
||||
@@ -0,0 +1,25 @@
|
||||
%! TeX program = lualatex
|
||||
%! TeX root = ../../thesis.tex
|
||||
\documentclass[../../thesis.tex]{subfiles}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\section{Missing FAIL\_MARKERs for AOT experiments}
|
||||
|
||||
\begin{itemize}
|
||||
\item AOT Addressauflösung/Def-Use chain theory
|
||||
\item Somehow caught by --catch-write-textsegment or --catch-outerspace because stuff was linked to .text?
|
||||
\item Optimization theory
|
||||
\begin{itemize}
|
||||
\item Does the target program contain the expected instructions?
|
||||
\item Does FAIL* treat the variables as not live? (volatile, fail\_stop\_trace(sum))
|
||||
\item Trying more complex programs, as -O0 always writes intermediate results to memory
|
||||
\item Swap fail\_marker\_positive and fail\_marker\_negative
|
||||
\end{itemize}
|
||||
\item Does the pruner clear those injections for some reason?
|
||||
\item Does the disassembler not disassemble the .text subsections?
|
||||
\item Is the TracingPlugin broken? (GDB -> No, but FAIL* doesn't trace register accesses)
|
||||
\item Solution: Gap in the .elf symbol space (addresses that are not covered by some symbol). FAIL needs this to disassemble the Wasm AOT code to find the register accesses. FAIL also needs to find this AOT code, so it can't be relocated -> Needs --xip
|
||||
\end{itemize}
|
||||
|
||||
\end{document}
|
||||
@@ -0,0 +1,14 @@
|
||||
%! TeX program = lualatex
|
||||
%! TeX root = ../../thesis.tex
|
||||
\documentclass[../../thesis.tex]{subfiles}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\section{Target Programs}
|
||||
|
||||
\begin{itemize}
|
||||
\item Toy examples
|
||||
\item TacleBench~\autocite{TACLeBench,seidlerTACLeBenchWasmConverter2026}
|
||||
\end{itemize}
|
||||
|
||||
\end{document}
|
||||
@@ -0,0 +1,15 @@
|
||||
// Define FAIL* marker symbols
|
||||
void fail_start_trace(void) {}
|
||||
void fail_stop_trace(void) {}
|
||||
void fail_marker_positive(void) {}
|
||||
void fail_marker_negative(void) {}
|
||||
void fail_marker_detected(void) {}
|
||||
|
||||
// Forward declare workload
|
||||
int wasm_module(void);
|
||||
|
||||
// Execute
|
||||
MAIN {
|
||||
int retval = wasm_module();
|
||||
RET(retval);
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
static RuntimeInitArgs init_args;
|
||||
memset(&init_args, 0, sizeof(RuntimeInitArgs));
|
||||
|
||||
// If using Alloc_With_Allocator:
|
||||
init_args.mem_alloc_type = Alloc_With_Allocator;
|
||||
init_args.mem_alloc_option.allocator.malloc_func = (void *)wamr_malloc;
|
||||
init_args.mem_alloc_option.allocator.realloc_func = (void *)wamr_realloc;
|
||||
init_args.mem_alloc_option.allocator.free_func = (void *)wamr_free;
|
||||
|
||||
// If using Alloc_With_Pool instead:
|
||||
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)) {
|
||||
goto error_cleanup;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
// Error handling is omitted
|
||||
char error_buf[128];
|
||||
|
||||
wasm_module_t module = wasm_runtime_load(
|
||||
module_array, module_array_length, error_buf, sizeof(error_buf));
|
||||
|
||||
wasm_module_inst_t module_inst = wasm_runtime_instantiate(
|
||||
module, STACK_SIZE, HEAP_SIZE, error_buf, sizeof(error_buf));
|
||||
|
||||
wasm_exec_env_t exec_env = wasm_runtime_create_exec_env(
|
||||
module_inst, STACK_SIZE);
|
||||
|
||||
wasm_function_inst_t func = wasm_runtime_lookup_function(
|
||||
module_inst, "wasm_module");
|
||||
|
||||
// Arguments can be supplied to the function
|
||||
// by passing a pointer to an args buffer.
|
||||
// No arguments are set here, but a single
|
||||
// slot is reserved for the return value.
|
||||
uint32_t argv[1];
|
||||
uint32_t argc = 0;
|
||||
wasm_runtime_call_wasm(exec_env, func, argc, argv);
|
||||
uint32_t retval = argv[0];
|
||||
@@ -0,0 +1,12 @@
|
||||
static NativeSymbol native_symbols[] = {
|
||||
{"fail_start_trace", (void *)host_fail_start_trace, "()", NULL},
|
||||
{"fail_stop_trace", (void *)host_fail_stop_trace, "()", NULL},
|
||||
{"fail_marker_positive", (void *)host_fail_marker_positive, "()", NULL},
|
||||
{"fail_marker_negative", (void *)host_fail_marker_negative, "()", NULL},
|
||||
{"fail_marker_detected", (void *)host_fail_marker_detected, "()", NULL},
|
||||
};
|
||||
|
||||
int count = sizeof(native_symbols) / sizeof(NativeSymbol);
|
||||
if (!wasm_runtime_register_natives("env", native_symbols, count)) {
|
||||
goto error_cleanup;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
// Define FAIL* marker symbols
|
||||
void fail_start_trace(void) {}
|
||||
void fail_stop_trace(void) {}
|
||||
void fail_marker_positive(void) {}
|
||||
void fail_marker_negative(void) {}
|
||||
void fail_marker_detected(void) {}
|
||||
|
||||
// Those functions can be called from within Wasm after registration
|
||||
void host_fail_start_trace(wasm_exec_env_t exec_env) {
|
||||
fail_start_trace();
|
||||
}
|
||||
void host_fail_stop_trace(wasm_exec_env_t exec_env) {
|
||||
fail_stop_trace();
|
||||
}
|
||||
void host_fail_marker_positive(wasm_exec_env_t exec_env) {
|
||||
fail_marker_positive();
|
||||
}
|
||||
void host_fail_marker_negative(wasm_exec_env_t exec_env) {
|
||||
fail_marker_negative();
|
||||
}
|
||||
void host_fail_marker_detected(wasm_exec_env_t exec_env) {
|
||||
fail_marker_detected();
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
extern "C" EXPORT("wasm_module") int wasm_module(void) {
|
||||
// Workload initialization
|
||||
int x = 0;
|
||||
|
||||
fail_start_trace();
|
||||
// Workload execution
|
||||
x = x + 1;
|
||||
fail_stop_trace();
|
||||
|
||||
// Success condition
|
||||
if (x == 1) {
|
||||
fail_marker_positive();
|
||||
return 0;
|
||||
} else {
|
||||
fail_marker_negative();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user