Initial Commit

This commit is contained in:
Ryan Houdek authored and Stefanos Kornilios Mitsis Poiitidis committed 2020-03-06 09:08:13 +02:00
1 parent e9ea4cbb76
commit 369686c992
73 files changed
+8820 -4

No files matched your search

+98
View File
@@ -0,0 +1,98 @@
#!/usr/bin/python3
from enum import Flag
import json
import os
import struct
import sys
import glob
from threading import Thread
import subprocess
import time
import multiprocessing
if sys.version_info[0] < 3:
raise Exception("Python 3 or a more recent version is required.")
if (len(sys.argv) < 3):
sys.exit("We need two arguments. Location of LockStepRunner and folder containing the tests")
# Remove our SHM regions if they still exist
SHM_Files = glob.glob("/dev/shm/*_Lockstep")
for file in SHM_Files:
os.remove(file)
UnitTests = sorted(glob.glob(sys.argv[2] + "*"))
UnitTestsSize = len(UnitTests)
Threads = [None] * UnitTestsSize
Results = [None] * UnitTestsSize
ThreadResults = [[None] * 2] * UnitTestsSize
MaxFileNameStringLen = 0
def Threaded_Runner(Args, ID, Client):
Log = open("Log_" + str(ID) + "_" + str(Client), "w")
Log.write("Args: %s\n" % " ".join(Args))
Log.flush()
Process = subprocess.Popen(Args, stdout=Log, stderr=Log)
Process.wait()
Log.flush()
ThreadResults[ID][Client] = Process.returncode
def Threaded_Manager(Runner, ID, File):
ServerArgs = ["catchsegv", Runner, "-c", "vm", "-n", "1", "-I", "R" + str(ID), File]
ClientArgs = ["catchsegv", Runner, "-c", "vm", "-n", "1", "-I", "R" + str(ID), "-C"]
ServerThread = Thread(target = Threaded_Runner, args = (ServerArgs, ID, 0))
ClientThread = Thread(target = Threaded_Runner, args = (ClientArgs, ID, 1))
ServerThread.start()
ClientThread.start()
ClientThread.join()
ServerThread.join()
# The server is the one we should listen to for results
if (ThreadResults[ID][1] != 0 and ThreadResults[ID][0] == 0):
# If the client died for some reason but server thought we were fine then take client data
Results[ID] = ThreadResults[ID][1]
else:
# Else just take the server data
Results[ID] = ThreadResults[ID][0]
DupLen = MaxFileNameStringLen - len(UnitTests[ID])
if (Results[ID] == 0):
print("\t'%s'%s - PASSED ID: %d - 0" % (UnitTests[ID], " "*DupLen, ID))
else:
print("\t'%s'%s - FAILED ID: %d - %s" % (UnitTests[ID], " "*DupLen, ID, hex(Results[ID])))
RunnerSlot = 0
MaxRunnerSlots = min(32, multiprocessing.cpu_count() / 2)
RunnerSlots = [None] * MaxRunnerSlots
for RunnerID in range(UnitTestsSize):
File = UnitTests[RunnerID]
print("'%s' Running Test" % File)
MaxFileNameStringLen = max(MaxFileNameStringLen, len(File))
Threads[RunnerID] = Thread(target = Threaded_Manager, args = (sys.argv[1], RunnerID, File))
Threads[RunnerID].start()
if (MaxRunnerSlots != 0):
RunnerSlots[RunnerSlot] = Threads[RunnerID]
RunnerSlot += 1
if (RunnerSlot == MaxRunnerSlots):
for i in range(MaxRunnerSlots):
RunnerSlots[i].join()
RunnerSlot = 0
for i in range(UnitTestsSize):
Threads[i].join()
print("====== PASSED RESULTS ======")
for i in range(UnitTestsSize):
DupLen = MaxFileNameStringLen - len(UnitTests[i])
if (Results[i] == 0):
print("\t'%s'%s - PASSED ID: %d - 0" % (UnitTests[i], " "*DupLen, i))
print("====== FAILED RESULTS ======")
for i in range(UnitTestsSize):
DupLen = MaxFileNameStringLen - len(UnitTests[i])
if (Results[i] != 0):
print("\t'%s'%s - FAILED ID: %d - %s" % (UnitTests[i], " "*DupLen, i, hex(Results[i])))
+229
View File
@@ -0,0 +1,229 @@
from enum import Flag
import json
import struct
import sys
class Regs(Flag):
REG_NONE = 0
REG_RIP = (1 << 0)
REG_RAX = (1 << 1)
REG_RBX = (1 << 2)
REG_RCX = (1 << 3)
REG_RDX = (1 << 4)
REG_RSI = (1 << 5)
REG_RDI = (1 << 6)
REG_RBP = (1 << 7)
REG_RSP = (1 << 8)
REG_R8 = (1 << 9)
REG_R9 = (1 << 10)
REG_R10 = (1 << 11)
REG_R11 = (1 << 12)
REG_R12 = (1 << 13)
REG_R13 = (1 << 14)
REG_R14 = (1 << 15)
REG_R15 = (1 << 16)
REG_XMM0 = (1 << 17)
REG_XMM1 = (1 << 18)
REG_XMM2 = (1 << 19)
REG_XMM3 = (1 << 20)
REG_XMM4 = (1 << 21)
REG_XMM5 = (1 << 22)
REG_XMM6 = (1 << 23)
REG_XMM7 = (1 << 24)
REG_XMM8 = (1 << 25)
REG_XMM9 = (1 << 26)
REG_XMM10 = (1 << 27)
REG_XMM11 = (1 << 28)
REG_XMM12 = (1 << 29)
REG_XMM13 = (1 << 30)
REG_XMM14 = (1 << 31)
REG_XMM15 = (1 << 32)
REG_GS = (1 << 33)
REG_FS = (1 << 34)
REG_FLAGS = (1 << 35)
REG_ALL = (1 << 36) - 1
REG_INVALID = (1 << 36)
class ABI(Flag) :
ABI_SYSTEMV = 0
ABI_WIN64 = 1
ABI_NONE = 2
RegStringLookup = {
"NONE": Regs.REG_NONE,
"RAX": Regs.REG_RAX,
"RIP": Regs.REG_RIP,
"RBX": Regs.REG_RBX,
"RCX": Regs.REG_RCX,
"RDX": Regs.REG_RDX,
"RSI": Regs.REG_RSI,
"RDI": Regs.REG_RDI,
"RBP": Regs.REG_RBP,
"RSP": Regs.REG_RSP,
"R8": Regs.REG_R8,
"R9": Regs.REG_R9,
"R10": Regs.REG_R10,
"R11": Regs.REG_R11,
"R12": Regs.REG_R12,
"R13": Regs.REG_R13,
"R14": Regs.REG_R14,
"R15": Regs.REG_R15,
"XMM0": Regs.REG_XMM0,
"XMM1": Regs.REG_XMM1,
"XMM2": Regs.REG_XMM2,
"XMM3": Regs.REG_XMM3,
"XMM4": Regs.REG_XMM4,
"XMM5": Regs.REG_XMM5,
"XMM6": Regs.REG_XMM6,
"XMM7": Regs.REG_XMM7,
"XMM8": Regs.REG_XMM8,
"XMM9": Regs.REG_XMM9,
"XMM10": Regs.REG_XMM10,
"XMM11": Regs.REG_XMM11,
"XMM12": Regs.REG_XMM12,
"XMM13": Regs.REG_XMM13,
"XMM14": Regs.REG_XMM14,
"XMM15": Regs.REG_XMM15,
"GS": Regs.REG_GS,
"FS": Regs.REG_FS,
"FLAGS": Regs.REG_FLAGS,
"ALL": Regs.REG_ALL,
}
ABIStringLookup = {
"SYSTEMV": ABI.ABI_SYSTEMV,
"WIN64": ABI.ABI_WIN64,
"NONE": ABI.ABI_NONE,
}
if (len(sys.argv) < 3):
sys.exit()
output_file = sys.argv[2]
asm_file = open(sys.argv[1], "r")
asm_text = asm_file.read()
asm_file.close()
# Default options
OptionMatch = Regs.REG_INVALID
OptionIgnore = Regs.REG_NONE
OptionABI = ABI.ABI_SYSTEMV
OptionStackSize = 4096
OptionEntryPoint = 1
OptionRegData = {}
OptionMemoryRegions = {}
json_text = asm_text.split("%ifdef CONFIG")
if (len(json_text) > 1):
json_text = json_text[1].split("%endif")
if (len(json_text) > 1):
json_text = json_text[0].strip()
json_object = json.loads(json_text)
json_object = {k.upper(): v for k, v in json_object.items()}
# Begin parsing the JSON
if ("MATCH" in json_object):
data = json_object["MATCH"]
if (type(data) is str):
data = [data]
for data_val in data:
data_val = data_val.upper()
if not (data_val in RegStringLookup):
sys.exit("Invalid Match register option")
if (OptionMatch == Regs.REG_INVALID):
OptionMatch = Regs.REG_NONE
RegOption = RegStringLookup[data_val]
OptionMatch = OptionMatch | RegOption
if ("IGNORE" in json_object):
data = json_object["IGNORE"]
if (type(data) is str):
data = [data]
for data_val in data:
data_val = data_val.upper()
if not (data_val in RegStringLookup):
sys.exit("Invalid Ignore register option")
if (OptionMatch == Regs.REG_INVALID):
OptionMatch = Regs.REG_NONE
RegOption = RegStringLookup[data_val]
OptionIgnore = OptionIgnore | RegOption
if ("ABI" in json_object):
data = json_object["ABI"]
data = data.upper()
if not (data in ABIStringLookup):
sys.exit("Invalid ABI")
OptionABI = ABIStringLookup[data]
if ("STACKSIZE" in json_object):
data = json_object["STACKSIZE"]
OptionStackSize = int(data, 0)
if ("ENTRYPOINT" in json_object):
data = json_object["ENTRYPOINT"]
data = int(data, 0)
if (data == 0):
sys.exit("Invalid entrypoint of 0")
OptionEntryPoint = data
if ("MEMORYREGIONS" in json_object):
data = json_object["MEMORYREGIONS"]
if not (type(data) is dict):
sys.exit("RegData value must be list of key:value pairs")
for data_key, data_val in data.items():
OptionMemoryRegions[int(data_key, 0)] = int(data_val, 0);
if ("REGDATA" in json_object):
data = json_object["REGDATA"]
if not (type(data) is dict):
sys.exit("RegData value must be list of key:value pairs")
for data_key, data_val in data.items():
data_key = data_key.upper()
if not (data_key in RegStringLookup):
sys.exit("Invalid RegData register option")
data_key_index = RegStringLookup[data_key]
data_key_values = []
# Create a list of values for this register as an integer
if (type(data_val) is list):
for data_key_value in data_val:
data_key_values.append(int(data_key_value, 0))
else:
data_key_values.append(int(data_val, 0))
OptionRegData[data_key_index] = data_key_values
# If Match option wasn't touched then set it to the default
if (OptionMatch == Regs.REG_INVALID):
OptionMatch = Regs.REG_NONE
config_file = open(output_file, "wb")
config_file.write(struct.pack('Q', OptionMatch.value))
config_file.write(struct.pack('Q', OptionIgnore.value))
config_file.write(struct.pack('Q', OptionStackSize))
config_file.write(struct.pack('Q', OptionEntryPoint))
config_file.write(struct.pack('I', OptionABI.value))
# Number of memory regions
config_file.write(struct.pack('I', len(OptionMemoryRegions)))
# Number of register values
config_file.write(struct.pack('I', len(OptionRegData)))
# Print number of memory regions
for reg_key, reg_val in OptionMemoryRegions.items():
config_file.write(struct.pack('Q', reg_key))
config_file.write(struct.pack('Q', reg_val))
# Print Register values
for reg_key, reg_val in OptionRegData.items():
config_file.write(struct.pack('I', len(reg_val)))
config_file.write(struct.pack('Q', reg_key.value))
for reg_vals in reg_val:
config_file.write(struct.pack('Q', reg_vals))
config_file.close()