To protect your data, the CISO officer has suggested users to enable GitLab 2FA as soon as possible.

Commit 62635f6d authored by Isaac Oscar Gariano's avatar Isaac Oscar Gariano
Browse files

Added a newframework to quickly write and test muir

parent 0d2cb2eb
You will need the python 2 version of pytest and (muc)[https://gitlab.anu.edu.au/mu/mu-tool-compiler].
You may find the following environemnt variables usefull:
* `MUC` (default _muc_) Set to the path to use to execute muc (or just put muc in your path)
* `MU_LOG_LEVEL` (default _none_) The log level used by zebu when building and running (Zebu will read this variable at compile time and runtime of your bootimage)
* `MU_EMIT_DIR` (default _emit_) The directory to store the stuff zebu emits
# Copyright 2017 The Australian National University
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from util import execute_bundle, load_bundle, get_function;
import pytest;
import ctypes;
def test_argc():
assert(execute_bundle(
"""
.funcdef test_argc <main_sig>
{
entry(<int<32>>argc <uptr<uptr<char>>>argv):
RET argc
}
""",
"test_argc", ["2", "3", "4"]) == 4);
@pytest.mark.xfail(reason = "1 bit division is not implemented on x86-64")
def test_int1():
assert(execute_bundle(
"""
.funcdef test_int <main_sig>
{
entry(<int<32>>argc <uptr<uptr<char>>>argv):
res10 = ADD <int<1>> <int<1>>1 <int<1>>1 // = 1
res11 = ADD <int<1>> res10 <int<1>>1 // = 1
res1 = UDIV <int<1>> res11 <int<1>>1 // = 1
res = ZEXT <int<1> int<32>> res1 // = 1
RET res
}
""",
"test_int") == 1);
def test_add():
lib = load_bundle(
"""
.funcdef test_add <(int<64> int<64>)->(int<64>)>
{
entry(<int<64>>a <int<64>>b):
res = ADD <int<64>> a b
RET res
}
""",
"test_add.so");
test_add = get_function(lib.test_add, [ctypes.c_int64, ctypes.c_int64], ctypes.c_int64);
assert(test_add(1, 2) == 3);
assert(test_add(-40, 60) == 20);
def test_except_stack_args():
assert(execute_bundle(
"""
.funcsig stack_sig = (int<64> int<64> int<64> int<64> int<64> int<64> int<64>)->()
.funcdef stack_args <stack_sig>
{
entry(<int<64>> v0 <int<64>> v1 <int<64>> v2 <int<64>> v3 <int<64>> v4 <int<64>> v5 <int<64>> v6):
THROW <ref<void>> NULL
}
.funcdef test_except_stack_args <main_sig>
{
entry(<int<32>>argc <uptr<uptr<char>>>argv):
CALL <stack_sig> stack_args(<int<32>>0 <int<32>>1 <int<32>>2 <int<32>>3 <int<32>>4 <int<32>>5 <int<32>>6)
EXC (exit(<int<32>> 0) exit(<int<32>> 1))
exit(<int<32>> status):
RET status
}
""",
"test_except_stack_args") == 1);
# Copyright 2017 The Australian National University
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os, subprocess, ctypes;
muc = os.environ.get('MUC', 'muc'); #type: str
emit = os.environ.get('MU_EMIT_DIR', 'emit'); #type: str
prelude = """
.funcsig exit_sig = (int<32>) -> ()
.typedef exit_type = ufuncptr<exit_sig>
.const exit <exit_type> = EXTERN "exit"
.typedef char = int<8>
.funcsig main_sig = (int<32> uptr<uptr<char>>)->(int<32>)
"""
""" Makes a primordial function that calls the given 'main' function (which should have the same signature as a C main function) """
def make_primordial(main): # type: (str) -> str
return """
.funcdef primordial <(int<32> uptr<uptr<char>>)->()>
{
entry(<int<32>>argc <uptr<uptr<char>>>argv):
res = CALL <main_sig> """ + main + """(argc argv)
CCALL #DEFAULT <exit_type exit_sig> exit(res)
RET // Unreachable
}""";
def get_output_file(name): # type: (str) -> str
return os.path.join(emit, name);
def execute_muc(bundle, name, primordial=None): # type: (str, str, Optional[str]) -> None
muc_proc = subprocess.Popen([muc, "-r"]
+ (["-f", primordial] if primordial is not None else [])
+ ["/dev/stdin", get_output_file(name)],
stdin = subprocess.PIPE); #type: subprocess.Popen
muc_proc.communicate(bundle); # Send the bundle to muc
assert (muc_proc.returncode == 0); # Check that muc worked
def execute_bundle(bundle, name, args = [], main = None): # type: (str, str, Optional[List[str]], Optional[str]) -> int
execute_muc(prelude + bundle + make_primordial(main if main is not None else name), name, "primordial");
return subprocess.call([get_output_file(name)] + args);
def load_bundle(bundle, name): # type: (str, str) -> ctypes.CDLL
execute_muc(prelude + bundle, name);
return ctypes.CDLL(get_output_file(name));
def get_function(func, argtypes, restype): # type: (ctypes._FuncPtr) -> (ctypes._FuncPtr)
func.argtypes = argtypes;
func.restype = restype;
return func;
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment