test(fuzz): Capability for random inputs
Adding model for random inputs to SMC calls using a
constraint mechanism with a multi tiered sanity
metric.
Change-Id: Ia750fa57359baa424f1af273ba24483ae7330c38
Signed-off-by: Mark Dykes <mark.dykes@arm.com>
diff --git a/smc_fuzz/dts/sdei.dts b/smc_fuzz/dts/sdei.dts
index a8199e1..8b55441 100644
--- a/smc_fuzz/dts/sdei.dts
+++ b/smc_fuzz/dts/sdei.dts
@@ -1,12 +1,9 @@
/*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-
-
-
/dts-v1/;
/ {
@@ -41,6 +38,10 @@
bias = <30>;
functionname = "sdei_shared_reset_funcid";
};
+ sdei_interrupt_bind {
+ bias = <30>;
+ functionname = "sdei_interrupt_bind_funcid";
+ };
};
};
diff --git a/smc_fuzz/include/constraint.h b/smc_fuzz/include/constraint.h
new file mode 100644
index 0000000..3a4af1d
--- /dev/null
+++ b/smc_fuzz/include/constraint.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef CONSTRAINT_H
+#define CONSTRAINT_H
+
+#include <stdint.h>
+#include "smcmalloc.h"
+
+#define SANITY_LEVEL_0 0
+#define SANITY_LEVEL_1 1
+#define SANITY_LEVEL_2 2
+#define SANITY_LEVEL_3 3
+
+#define FUZZER_CONSTRAINT_SVALUE 0
+#define FUZZER_CONSTRAINT_RANGE 1
+#define FUZZER_CONSTRAINT_VECTOR 2
+
+#define FUZZER_CONSTRAINT_ACCMODE 0
+#define FUZZER_CONSTRAINT_EXCMODE 1
+
+#define FUZZ_MAX_SHIFT_AMNT 16
+#define FUZZ_MAX_REG_SIZE 64
+#define FUZZ_MAX_NAME_SIZE 80
+
+struct inputparameters {
+ uint64_t x1;
+ uint64_t x2;
+ uint64_t x3;
+ uint64_t x4;
+ uint64_t x5;
+ uint64_t x6;
+ uint64_t x7;
+ uint64_t x8;
+ uint64_t x9;
+ uint64_t x10;
+ uint64_t x11;
+ uint64_t x12;
+ uint64_t x13;
+ uint64_t x14;
+ uint64_t x15;
+ uint64_t x16;
+ uint64_t x17;
+};
+
+void setconstraint(int contype, uint64_t *vecinput, int veclen, int fieldnameptr, struct memmod *mmod, int mode);
+struct inputparameters generate_args(int smccall, int sanity);
+uint64_t get_generated_value(int fieldnameptr, struct inputparameters inp);
+void print_smccall(int smccall, struct inputparameters inp);
+#endif /* CONSTRAINT_H */
diff --git a/smc_fuzz/include/sdei_fuzz_helper.h b/smc_fuzz/include/sdei_fuzz_helper.h
index cf4ddd1..72c179d 100644
--- a/smc_fuzz/include/sdei_fuzz_helper.h
+++ b/smc_fuzz/include/sdei_fuzz_helper.h
@@ -5,6 +5,8 @@
*/
#include <fuzz_helper.h>
+#include "smcmalloc.h"
+
#include <power_management.h>
#include <sdei.h>
#include <test_helpers.h>
@@ -36,4 +38,4 @@
void tftf_test_sdei_noarg(int64_t (*sdei_func)(void), char *funcstr);
void tftf_test_sdei_singlearg(int64_t (*sdei_func)(uint64_t), char *funcstr);
-void run_sdei_fuzz(int funcid);
+void run_sdei_fuzz(int funcid, struct memmod *mmod);
diff --git a/smc_fuzz/include/smcmalloc.h b/smc_fuzz/include/smcmalloc.h
index fe134bf..97b33e9 100644
--- a/smc_fuzz/include/smcmalloc.h
+++ b/smc_fuzz/include/smcmalloc.h
@@ -52,12 +52,12 @@
};
void initmem(void);
-struct peret priorityencoder(unsigned int);
-void *smcmalloc(unsigned int, struct memmod*);
-int smcfree(void*, struct memmod *);
+struct peret priorityencoder(unsigned int ennum);
+void *smcmalloc(unsigned int req, struct memmod *mmod);
+int smcfree(void *vin, struct memmod *mmod);
#ifdef DEBUG_SMC_MALLOC
-void displayblocks(struct memmod *);
-void displaymalloctable(struct memmod *);
+void displayblocks(struct memmod *mmod);
+void displaymalloctable(struct memmod *mmod);
#endif
#endif /* SMCMALLOC_H */
diff --git a/smc_fuzz/script/gen_arg_struct_def.py b/smc_fuzz/script/gen_arg_struct_def.py
new file mode 100755
index 0000000..ce24679
--- /dev/null
+++ b/smc_fuzz/script/gen_arg_struct_def.py
@@ -0,0 +1,69 @@
+#
+# Copyright (c) 2025 Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+def gen_arg_struct_def(asdname,argfieldname,arglst,argnumfield):
+ asdfile = open(asdname, "w")
+ hline = "/*\n"
+ hline += " * Copyright (c) 2024, Arm Limited. All rights reserved.\n"
+ hline += " *\n"
+ hline += " * SPDX-License-Identifier: BSD-3-Clause\n"
+ hline += " */\n"
+ hline += "\n"
+ hline += "#ifndef ARG_STRUCT_DEF_H\n"
+ hline += "#define ARG_STRUCT_DEF_H\n"
+ hline += "\n"
+ asdfile.write(hline)
+ smccount = 0
+ argcount = 0
+ for sn in argfieldname:
+ hline = "#define "
+ hline += sn
+ hline += " "
+ hline += str(smccount)
+ hline += "\n"
+ asdfile.write(hline)
+ smccount = smccount + 1
+ smccount = smccount - 1
+ hline = "#define MAX_SMC_CALLS "
+ hline += str(smccount)
+ hline += "\n"
+ asdfile.write(hline)
+ asdfile.write("\n")
+ for sn in arglst:
+ for an in arglst[sn]:
+ hline = "#define "
+ hline += sn
+ hline += "_ARG" + str(an) + " " + str(argcount)
+ hline += "\n"
+ asdfile.write(hline)
+ argcount = argcount + 1
+ argcount = argcount - 1
+ hline = "#define MAX_ARG_LENGTH "
+ hline += str(argcount)
+ hline += "\n\n"
+ asdfile.write(hline)
+ for sn in argnumfield:
+ for ag in argnumfield[sn]:
+ fieldcount = 0
+ for fn in argnumfield[sn][ag]:
+ hline = "#define " + sn + "_ARG" + str(argnumfield[sn][ag][fn]) + "_" + fn.upper() + "_CNT " + str(fieldcount)
+ hline += "\n"
+ asdfile.write(hline)
+ fieldcount = fieldcount + 1
+ fieldcount = 0
+ hline = "\n\n"
+ asdfile.write(hline)
+ for sn in argnumfield:
+ for ag in argnumfield[sn]:
+ for fn in argnumfield[sn][ag]:
+ hline = "#define " + sn + "_ARG" + str(argnumfield[sn][ag][fn]) + "_" + fn.upper() + " " + str(fieldcount)
+ hline += "\n"
+ asdfile.write(hline)
+ fieldcount = fieldcount + 1
+ hline = "\n#endif /* ARG_STRUCT_DEF_H */\n"
+ asdfile.write(hline)
+
+ asdfile.close()
diff --git a/smc_fuzz/script/gen_field_specification.py b/smc_fuzz/script/gen_field_specification.py
new file mode 100755
index 0000000..86eff31
--- /dev/null
+++ b/smc_fuzz/script/gen_field_specification.py
@@ -0,0 +1,152 @@
+#
+# Copyright (c) 2025 Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+def gen_field_specification(fsname,argfieldname,argendbit,argstartbit,argdefval,argnumfield):
+ faafile = open(fsname, "w")
+ hline = "struct fuzzer_arg_def {\n"
+ hline += " int regnum;\n"
+ hline += " char smcname[FUZZ_MAX_NAME_SIZE];\n"
+ hline += " char smcargname[FUZZ_MAX_NAME_SIZE];\n"
+ hline += " int bitw;\n"
+ hline += " int bitst;\n"
+ hline += " char bnames[FUZZ_MAX_NAME_SIZE];\n"
+ hline += " uint64_t defval;\n"
+ hline += " uint64_t **contval;\n"
+ hline += " int *contvallen;\n"
+ hline += " int contlen;\n"
+ hline += " int *conttype;\n"
+ hline += " int genvalues;\n"
+ hline += "};\n\n"
+ hline += "struct fuzzer_arg_arange {\n"
+ hline += " int arg_span[2];\n"
+ hline += "};\n"
+ faafile.write(hline)
+ hline = "struct fuzzer_arg_def fuzzer_arg_array[] = {\n"
+ faafile.write(hline)
+ ifield = 1
+ for sn in argfieldname:
+ for an in argfieldname[sn]:
+ for fn in argfieldname[sn][an]:
+ if not ifield:
+ hline = ",\n"
+ hline += "{ .bitw = "
+ else:
+ hline = "{ .bitw = "
+ hline += str((int(argendbit[sn][an][fn]) - int(argstartbit[sn][an][fn])) + 1)
+ hline += ", .bitst = " + argstartbit[sn][an][fn] + ", .bnames = \""
+ hline += fn + "\", .defval = " + argdefval[sn][an][fn] + ", .regnum = "
+ hline += argnumfield[sn][an][fn] + ", .smcname = \"" + sn + "\", .smcargname = \""
+ hline += an + "\" }"
+ ifield = 0
+ faafile.write(hline)
+ hline = " };\n\n"
+ faafile.write(hline)
+ lc = 0
+ hline = "struct fuzzer_arg_arange fuzzer_arg_array_lst[] = {" + "\n"
+ faafile.write(hline)
+ ifield = 1
+ for sn in argfieldname:
+ for ag in argfieldname[sn]:
+ if not ifield:
+ hline = ",\n"
+ hline += "{ .arg_span = {" + str(lc) + "," + str(len(argfieldname[sn][ag]) - 1 + lc) + "} }"
+ else :
+ hline = "{ .arg_span = {" + str(lc) + "," + str(len(argfieldname[sn][ag]) - 1 + lc) + "} }"
+ ifield = 0
+ faafile.write(hline)
+ lc = lc + len(argfieldname[sn][ag])
+ hline = " };\n\n"
+ faafile.write(hline)
+ hline = "int fuzzer_arg_array_range[] = {" + "\n"
+ faafile.write(hline)
+ lc = 0
+ ifield = 1
+ hline = ""
+ for sn in argfieldname:
+ if not ifield:
+ hline += ","
+ hline += str(len(argfieldname[sn]))
+ else:
+ hline += str(len(argfieldname[sn]))
+ lc = lc + 1
+ ifield = 0
+ if lc == 20:
+ hline += "\n"
+ lc = 0
+ hline += "};\n\n"
+ faafile.write(hline)
+ hline = "int fuzzer_arg_array_start[] = {" + "\n"
+ faafile.write(hline)
+ lc = 0
+ ifield = 1
+ cargs = 0
+ hline = ""
+ for sn in argfieldname:
+ if not ifield:
+ hline += ","
+ hline += str(cargs)
+ else:
+ hline += str(cargs)
+ cargs = cargs + len(argfieldname[sn])
+ lc = lc + 1
+ ifield = 0
+ if lc == 20:
+ hline += "\n"
+ lc = 0
+ hline += "};\n\n"
+ faafile.write(hline)
+ hline = "int fuzzer_fieldarg[] = {" + "\n"
+ faafile.write(hline)
+ blist = 1
+ hline = "\t"
+ for sn in argnumfield:
+ for ag in argnumfield[sn]:
+ for fn in argnumfield[sn][ag]:
+ if not blist:
+ hline += ",\n\t"
+ blist = 0
+ hline += sn + "_ARG" + str(argnumfield[sn][ag][fn])
+ faafile.write(hline)
+ hline = ""
+ hline = "\n};"
+ faafile.write(hline)
+ hline = "\n\n"
+ faafile.write(hline)
+ hline = "int fuzzer_fieldcall[] = {" + "\n"
+ faafile.write(hline)
+ blist = 1
+ hline = "\t"
+ for sn in argnumfield:
+ for ag in argnumfield[sn]:
+ for fn in argnumfield[sn][ag]:
+ if not blist:
+ hline += ",\n\t"
+ blist = 0
+ hline += sn
+ faafile.write(hline)
+ hline = ""
+ hline = "\n};"
+ faafile.write(hline)
+ hline = "\n\n"
+ faafile.write(hline)
+ hline = "int fuzzer_fieldfld[] = {" + "\n"
+ faafile.write(hline)
+ blist = 1
+ hline = "\t"
+ for sn in argnumfield:
+ for ag in argnumfield[sn]:
+ for fn in argnumfield[sn][ag]:
+ if not blist:
+ hline += ",\n\t"
+ blist = 0
+ hline += sn + "_ARG" + str(argnumfield[sn][ag][fn]) + "_" + fn.upper() + "_CNT"
+ faafile.write(hline)
+ hline = ""
+ hline = "\n};"
+
+ faafile.write(hline)
+
+ faafile.close()
diff --git a/smc_fuzz/script/generate_smc.py b/smc_fuzz/script/generate_smc.py
new file mode 100755
index 0000000..dac5924
--- /dev/null
+++ b/smc_fuzz/script/generate_smc.py
@@ -0,0 +1,45 @@
+# !/usr/bin/env python
+#
+# Copyright (c) 2025 Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+
+#python3 generate_smc.py -s smclist
+#This script generated C files after the read of the SMC description/list file
+import argparse
+import readsmclist
+import gen_arg_struct_def
+import gen_field_specification
+
+parser = argparse.ArgumentParser(
+ prog='generate_smc.py',
+ description='Generates SMC code to add to fuzzer library',
+ epilog='one argument input')
+
+parser.add_argument('-s', '--smclist',help="SMC list file .")
+
+args = parser.parse_args()
+
+print("starting generate SMC")
+
+seq = 0
+
+readsmclist.readsmclist(args.smclist,seq)
+
+arglst = readsmclist.arglst
+argnumfield = readsmclist.argnumfield
+argfieldname = readsmclist.argfieldname
+argstartbit = readsmclist.argstartbit
+argendbit = readsmclist.argendbit
+argdefval = readsmclist.argdefval
+smcname = readsmclist.smcname
+argnum = readsmclist.argnum
+argname = readsmclist.argname
+
+gen_arg_struct_def.gen_arg_struct_def("./include/arg_struct_def.h",argfieldname,arglst,argnumfield)
+
+gen_field_specification.gen_field_specification("./include/field_specification.h",
+argfieldname,argendbit,argstartbit,argdefval,argnumfield)
+
diff --git a/smc_fuzz/script/readsmclist.py b/smc_fuzz/script/readsmclist.py
new file mode 100755
index 0000000..3bfcb6a
--- /dev/null
+++ b/smc_fuzz/script/readsmclist.py
@@ -0,0 +1,193 @@
+#
+# Copyright (c) 2025 Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+import re
+import copy
+import sys
+
+arglst = {}
+argnumfield = {}
+argfieldname = {}
+argstartbit = {}
+argendbit = {}
+argdefval = {}
+smcname = ""
+argnum = ""
+argname = ""
+
+def readsmclist(smclist,seq):
+ smclistfile = open(smclist, "r")
+ smclist_lines = smclistfile.readlines()
+ smclistfile.close()
+ for sline in smclist_lines:
+ lcon = 0
+ sl = sline.strip()
+ sinstr = re.search(r'^smc:\s*([a-zA-Z0-9_]+)$',sl)
+ if sinstr:
+ smcname = sinstr.group(1)
+ arglst[sinstr.group(1)] = []
+ argnumfield[sinstr.group(1)] = {}
+ argfieldname[sinstr.group(1)] = {}
+ argstartbit[sinstr.group(1)] = {}
+ argendbit[sinstr.group(1)] = {}
+ argdefval[sinstr.group(1)] = {}
+ lcon = 1
+ argoccupy = {}
+ if not seq:
+ seq = seq + 1
+ else:
+ if seq != 2:
+ print("Error: out of sequence for smc call",end=" ")
+ print(smcname)
+ sys.exit()
+ else:
+ seq = 1
+ sinstr = re.search(r'^arg(\d+)\s*:\s*([a-zA-Z0-9_]+)$',sl)
+ if sinstr:
+ if sinstr.group(1) in argoccupy:
+ print("Error: register already specified for SMC call",end=" ")
+ print(smcname,end=" ")
+ print("argument",end=" ")
+ print(sinstr.group(1))
+ sys.exit()
+ argnum = sinstr.group(1)
+ argname = sinstr.group(2)
+ arglst[smcname].append(argnum)
+ argnumfield[smcname][sinstr.group(2)] = {}
+ argfieldname[smcname][sinstr.group(2)] = []
+ argstartbit[smcname][sinstr.group(2)] = {}
+ argendbit[smcname][sinstr.group(2)] = {}
+ argdefval[smcname][sinstr.group(2)] = {}
+ lcon = 1
+ argoccupy[argnum] = 1
+ fieldoccupy = []
+ if seq != 1:
+ if seq != 2:
+ print("Error: out of sequence for arg(value)",end=" ")
+ print("arg",end=" ")
+ print(argnum,end=" ")
+ print("for argname",end=" ")
+ print(argname)
+ sys.exit()
+ else:
+ seq = 2
+ else:
+ seq = seq + 1
+
+ sinstr = re.search(r'^arg(\d+)\s*=\s*(0x[a-fA-F0-9]+|\d+)$',sl)
+ if sinstr:
+ if sinstr.group(1) in argoccupy:
+ print("Error: register already specified for SMC call",end=" ")
+ print(smcname,end=" ")
+ print("argument",end=" ")
+ print(sinstr.group(1))
+ sys.exit()
+ srange = sinstr.group(1)
+ argrangename = smcname + "_args_"+ sinstr.group(1)
+ argnum = srange
+ argname = smcname + "_arg_" + argnum
+ fieldnameargdef = smcname + "_arg_" + argnum + "_field"
+ arglst[smcname].append(argnum)
+ argnumfield[smcname][argname] = {}
+ argfieldname[smcname][argname] = []
+ argstartbit[smcname][argname] = {}
+ argendbit[smcname][argname] = {}
+ argdefval[smcname][argname] = {}
+ argnumfield[smcname][argname][fieldnameargdef] = argnum
+ argfieldname[smcname][argname].append(fieldnameargdef)
+ argstartbit[smcname][argname][fieldnameargdef] = str(0)
+ argendbit[smcname][argname][fieldnameargdef] = str(63)
+ argdefval[smcname][argname][fieldnameargdef] = sinstr.group(2)
+ lcon = 1
+ argoccupy[argnum] = 1
+ if seq != 1:
+ if seq != 2:
+ print("Error: out of sequence for arg(value)",end=" ")
+ print("arg",end=" ")
+ print(argnum,end=" ")
+ print("for argname",end=" ")
+ print(argname)
+ sys.exit()
+ else:
+ seq = seq + 1
+ sinstr = re.search(r'^arg(\d+)-arg(\d+)\s*=\s*(0x[a-fA-F0-9]+|\d+)$',sl)
+ if sinstr:
+ srange = int(sinstr.group(1))
+ erange = int(sinstr.group(2))
+ argrangename = smcname + "_args_"+ sinstr.group(1) + "_" + sinstr.group(2)
+ for i in range((erange - srange) + 1):
+ if str(srange + i) in argoccupy:
+ print("Error: register already specified for SMC call",end=" ")
+ print(smcname,end=" ")
+ print("argument",end=" ")
+ print(str(srange + i))
+ sys.exit()
+ argnum = srange + i
+ argname = smcname + "_arg_" + str(argnum)
+ fieldnameargdef = smcname + "_arg_" + str(argnum) + "_field"
+ arglst[smcname].append(argnum)
+ argnumfield[smcname][argname] = {}
+ argfieldname[smcname][argname] = []
+ argstartbit[smcname][argname] = {}
+ argendbit[smcname][argname] = {}
+ argdefval[smcname][argname] = {}
+ argnumfield[smcname][argname][fieldnameargdef] = str(argnum)
+ argfieldname[smcname][argname].append(fieldnameargdef)
+ argstartbit[smcname][argname][fieldnameargdef] = str(0)
+ argendbit[smcname][argname][fieldnameargdef] = str(63)
+ argdefval[smcname][argname][fieldnameargdef] = sinstr.group(3)
+ argoccupy[str(argnum)] = 1
+ lcon = 1
+ if seq != 1:
+ if seq != 2:
+ print("Error: out of sequence for arg(value)",end=" ")
+ print("arg",end=" ")
+ print(argnum,end=" ")
+ print("for argname",end=" ")
+ print(argname)
+ sys.exit()
+ else:
+ seq = 2
+ else:
+ seq = seq + 1
+ sinstr = re.search(r'^field:([a-zA-Z0-9_]+):\[(\d+),(\d+)\]\s*=\s*(0x[a-fA-F0-9]+|\d+)$',sl)
+ if sinstr:
+ for fs in fieldoccupy:
+ if(((fs[0] <= int(sinstr.group(3))) and (fs[0] >= int(sinstr.group(2)))) or
+ ((fs[1] <= int(sinstr.group(3))) and (fs[1] >= int(sinstr.group(2))))):
+ print("Error: field overlap",end=" ")
+ print(smcname,end=" ")
+ print(argname,end=" ")
+ print(sinstr.group(1),end=" ")
+ print(fs[0],end=" ")
+ print(fs[1],end=" ")
+ print(" with",end=" ")
+ print(sinstr.group(2),end=" ")
+ print(sinstr.group(3))
+ sys.exit()
+ argnumfield[smcname][argname][sinstr.group(1)] = argnum
+ argfieldname[smcname][argname].append(sinstr.group(1))
+ argstartbit[smcname][argname][sinstr.group(1)] = sinstr.group(2)
+ argendbit[smcname][argname][sinstr.group(1)] = sinstr.group(3)
+ argdefval[smcname][argname][sinstr.group(1)] = sinstr.group(4)
+ flist = []
+ flist.append(int(sinstr.group(2)))
+ flist.append(int(sinstr.group(3)))
+ fieldoccupy.append(flist)
+ lcon = 1
+ if seq != 2:
+ print("Error: out of sequence for field")
+ sys.exit()
+ if not lcon:
+ cline = re.search(r'^#',sl)
+ if not cline:
+ if sl:
+ print("Error: malformed line at",end=" ")
+ print(sl)
+ sys.exit()
+ if(seq != 2):
+ print("incorrect ending for smc specification")
+ sys.exit()
diff --git a/smc_fuzz/src/constraint.c b/smc_fuzz/src/constraint.c
new file mode 100644
index 0000000..7e4c4b5
--- /dev/null
+++ b/smc_fuzz/src/constraint.c
@@ -0,0 +1,1040 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arg_struct_def.h>
+#include <constraint.h>
+#include <field_specification.h>
+
+#include <debug.h>
+
+#ifdef SMC_FUZZ_TMALLOC
+#define GENMALLOC(x) malloc((x))
+#define GENFREE(x) free((x))
+#else
+#define GENMALLOC(x) smcmalloc((x), mmod)
+#define GENFREE(x) smcfree((x), mmod)
+#endif
+
+/*******************************************************
+* Random 64 bit generator for registers
+*******************************************************/
+
+uint64_t rand64bit(void)
+{
+ uint64_t xreg = (rand() % (1 << FUZZ_MAX_SHIFT_AMNT)) << FUZZ_MAX_SHIFT_AMNT;
+
+ xreg = ((rand() % (1 << FUZZ_MAX_SHIFT_AMNT)) | xreg) << FUZZ_MAX_SHIFT_AMNT;
+ xreg = ((rand() % (1 << FUZZ_MAX_SHIFT_AMNT)) | xreg) << FUZZ_MAX_SHIFT_AMNT;
+ xreg = ((rand() % (1 << FUZZ_MAX_SHIFT_AMNT)) | xreg);
+ return xreg;
+}
+
+/*******************************************************
+* Shift left function for registers
+*******************************************************/
+
+uint64_t shiftlft(uint64_t val, int shamnt)
+{
+ uint64_t ressh = val;
+
+ if (shamnt > FUZZ_MAX_REG_SIZE) {
+ printf("Error: cannot shift beyond %d bits\n", FUZZ_MAX_REG_SIZE);
+ panic();
+ }
+ if (shamnt > FUZZ_MAX_SHIFT_AMNT) {
+ for (int i = 0; i < ((shamnt / FUZZ_MAX_SHIFT_AMNT) + 1); i++) {
+ if (i == (shamnt / FUZZ_MAX_SHIFT_AMNT)) {
+ ressh = ressh << (shamnt % FUZZ_MAX_SHIFT_AMNT);
+ } else {
+ ressh = ressh << FUZZ_MAX_SHIFT_AMNT;
+ }
+ }
+ } else {
+ ressh = ressh << shamnt;
+ }
+ return ressh;
+}
+
+/*******************************************************
+* Shift right function for registers
+*******************************************************/
+
+uint64_t shiftrht(uint64_t val, int shamnt)
+{
+ uint64_t ressh = val;
+
+ if (shamnt > FUZZ_MAX_REG_SIZE) {
+ printf("Error: cannot shift beyond %d bits\n", FUZZ_MAX_REG_SIZE);
+ panic();
+ }
+ if (shamnt > FUZZ_MAX_SHIFT_AMNT) {
+ for (int i = 0; i < ((shamnt / FUZZ_MAX_SHIFT_AMNT) + 1); i++) {
+ if (i == (shamnt / FUZZ_MAX_SHIFT_AMNT)) {
+ ressh = ressh >> (shamnt % FUZZ_MAX_SHIFT_AMNT);
+ } else {
+ ressh = ressh >> FUZZ_MAX_SHIFT_AMNT;
+ }
+ }
+ } else {
+ ressh = ressh >> shamnt;
+ }
+ return ressh;
+}
+
+/*******************************************************
+* Set constraints for the fields in the SMC call
+*******************************************************/
+
+
+void setconstraint(int contype, uint64_t *vecinput, int veclen, int fieldnameptr, struct memmod *mmod, int mode)
+{
+ int argdef = fuzzer_fieldarg[fieldnameptr];
+ int fieldname = fuzzer_fieldfld[fieldnameptr];
+
+ if ((argdef > MAX_ARG_LENGTH) || (argdef < 0)) {
+ printf("SMC argument is out of bounds\n");
+ panic();
+ }
+ if ((fieldname > (fuzzer_arg_array_lst[argdef].arg_span[1] -
+ fuzzer_arg_array_lst[argdef].arg_span[0])) || (fieldname < 0)) {
+ printf("SMC fieldname is out of bounds\n");
+ panic();
+ }
+ int fieldptr = fuzzer_arg_array_lst[argdef].arg_span[0] + fieldname;
+
+ if ((contype > FUZZER_CONSTRAINT_VECTOR) || (contype < 0)) {
+ printf("SMC constraint type is out of bounds\n");
+ panic();
+ }
+ if (mode > 2) {
+ printf("SMC constriant mode input is invalid\n");
+ panic();
+ }
+ if (mmod == NULL) {
+ printf("SMC constraint memory pointer is invalid\n");
+ panic();
+ }
+ if (contype == FUZZER_CONSTRAINT_SVALUE) {
+ if (veclen < 1) {
+ printf("vector length to constraint for single value is not large enough");
+ printf(" %d", veclen);
+ panic();
+ }
+ if (vecinput == NULL) {
+ printf("vector input to constraint single value is not defined\n");
+ panic();
+ }
+ if (fuzzer_arg_array[fieldptr].contval == NULL) {
+ fuzzer_arg_array[fieldptr].contval = GENMALLOC(1 * sizeof(uint64_t **));
+ fuzzer_arg_array[fieldptr].contval[0] = GENMALLOC(1 * sizeof(uint64_t *));
+ fuzzer_arg_array[fieldptr].contval[0][0] = vecinput[0];
+ fuzzer_arg_array[fieldptr].contvallen = GENMALLOC(1 * sizeof(int *));
+ fuzzer_arg_array[fieldptr].contvallen[0] = 1;
+ fuzzer_arg_array[fieldptr].contlen = 1;
+ fuzzer_arg_array[fieldptr].conttype = GENMALLOC(1 * sizeof(int *));
+ fuzzer_arg_array[fieldptr].conttype[0] = contype;
+ } else {
+ if (mode == FUZZER_CONSTRAINT_ACCMODE) {
+ for (int i = 0; i < fuzzer_arg_array[fieldptr].contlen; i++) {
+ if (fuzzer_arg_array[fieldptr].conttype[i] ==
+ FUZZER_CONSTRAINT_SVALUE) {
+ if (fuzzer_arg_array[fieldptr].contval[i][0] == vecinput[0]) {
+ return;
+ }
+ }
+ }
+ uint64_t **tarray;
+
+ tarray = GENMALLOC((1 + fuzzer_arg_array[fieldptr].contlen)
+ * sizeof(uint64_t **));
+ for (int i = 0; i < fuzzer_arg_array[fieldptr].contlen; i++) {
+ tarray[i] = GENMALLOC(fuzzer_arg_array[fieldptr].contvallen[i]
+ * sizeof(uint64_t *));
+ for (int k = 0; k < fuzzer_arg_array[fieldptr].contvallen[i]; k++) {
+ tarray[i][k] = fuzzer_arg_array[fieldptr].contval[i][k];
+ }
+ }
+ tarray[fuzzer_arg_array[fieldptr].contlen] = GENMALLOC(1 * sizeof(int *));
+ tarray[fuzzer_arg_array[fieldptr].contlen][0] = vecinput[0];
+ for (int i = 0; i < fuzzer_arg_array[fieldptr].contlen; i++) {
+ GENFREE(fuzzer_arg_array[fieldptr].contval[i]);
+ }
+ GENFREE(fuzzer_arg_array[fieldptr].contval);
+ fuzzer_arg_array[fieldptr].contval = tarray;
+ int *tarraysingle;
+
+ tarraysingle = GENMALLOC((1 + fuzzer_arg_array[fieldptr].contlen) * sizeof(int *));
+ for (int i = 0; i < fuzzer_arg_array[fieldptr].contlen; i++) {
+ tarraysingle[i] = fuzzer_arg_array[fieldptr].contvallen[i];
+ }
+ tarraysingle[fuzzer_arg_array[fieldptr].contlen] = 1;
+ GENFREE(fuzzer_arg_array[fieldptr].contvallen);
+ fuzzer_arg_array[fieldptr].contvallen = tarraysingle;
+ tarraysingle = GENMALLOC((1 + fuzzer_arg_array[fieldptr].contlen)
+ * sizeof(int *));
+ for (int i = 0; i < fuzzer_arg_array[fieldptr].contlen; i++) {
+ tarraysingle[i] = fuzzer_arg_array[fieldptr].conttype[i];
+ }
+ tarraysingle[fuzzer_arg_array[fieldptr].contlen] = contype;
+ GENFREE(fuzzer_arg_array[fieldptr].conttype);
+ fuzzer_arg_array[fieldptr].conttype = tarraysingle;
+ fuzzer_arg_array[fieldptr].contlen++;
+ }
+ if (mode == FUZZER_CONSTRAINT_EXCMODE) {
+ for (int i = 0; i < fuzzer_arg_array[fieldptr].contlen; i++) {
+ GENFREE(fuzzer_arg_array[fieldptr].contval[i]);
+ }
+ GENFREE(fuzzer_arg_array[fieldptr].contval);
+ GENFREE(fuzzer_arg_array[fieldptr].contvallen);
+ GENFREE(fuzzer_arg_array[fieldptr].conttype);
+ fuzzer_arg_array[fieldptr].contval = GENMALLOC(1 * sizeof(uint64_t **));
+ fuzzer_arg_array[fieldptr].contval[0] = GENMALLOC(1 * sizeof(uint64_t *));
+ fuzzer_arg_array[fieldptr].contval[0][0] = vecinput[0];
+ fuzzer_arg_array[fieldptr].contvallen = GENMALLOC(1 * sizeof(int *));
+ fuzzer_arg_array[fieldptr].contvallen[0] = 1;
+ fuzzer_arg_array[fieldptr].contlen = 1;
+ fuzzer_arg_array[fieldptr].conttype = GENMALLOC(1 * sizeof(int *));
+ fuzzer_arg_array[fieldptr].conttype[0] = contype;
+ }
+ }
+ }
+ if (contype == FUZZER_CONSTRAINT_RANGE) {
+ if (veclen < 2) {
+ printf("vector length to constraint for range is not large enough");
+ printf(" %d", veclen);
+ panic();
+ }
+ if (vecinput == NULL) {
+ printf("vector inputs to constraint for range is not defined\n");
+ panic();
+ }
+ if (fuzzer_arg_array[fieldptr].contval == NULL) {
+ fuzzer_arg_array[fieldptr].contval = GENMALLOC(1 * sizeof(uint64_t **));
+ fuzzer_arg_array[fieldptr].contval[0] = GENMALLOC(2 * sizeof(uint64_t *));
+ fuzzer_arg_array[fieldptr].contval[0][0] = vecinput[0];
+ fuzzer_arg_array[fieldptr].contval[0][1] = vecinput[1];
+ fuzzer_arg_array[fieldptr].contvallen = GENMALLOC(1 * sizeof(int *));
+ fuzzer_arg_array[fieldptr].contvallen[0] = 2;
+ fuzzer_arg_array[fieldptr].contlen = 1;
+ fuzzer_arg_array[fieldptr].conttype = GENMALLOC(1 * sizeof(int *));
+ fuzzer_arg_array[fieldptr].conttype[0] = contype;
+ } else {
+ if (mode == FUZZER_CONSTRAINT_ACCMODE) {
+ for (int i = 0; i < fuzzer_arg_array[fieldptr].contlen; i++) {
+ if (fuzzer_arg_array[fieldptr].conttype[i] ==
+ FUZZER_CONSTRAINT_RANGE) {
+ if ((fuzzer_arg_array[fieldptr].contval[i][0] ==
+ vecinput[0]) && (fuzzer_arg_array[fieldptr].contval[i][1]
+ == vecinput[1])) {
+ return;
+ }
+ }
+ }
+ uint64_t **tarray;
+
+ tarray = GENMALLOC((1 + fuzzer_arg_array[fieldptr].contlen)
+ * sizeof(uint64_t **));
+ for (int i = 0; i < fuzzer_arg_array[fieldptr].contlen; i++) {
+ tarray[i] =
+ GENMALLOC(fuzzer_arg_array[fieldptr].contvallen[i]
+ * sizeof(uint64_t *));
+ for (int k = 0; k < fuzzer_arg_array[fieldptr].contvallen[i]; k++) {
+ tarray[i][k] = fuzzer_arg_array[fieldptr].contval[i][k];
+ }
+ }
+ tarray[fuzzer_arg_array[fieldptr].contlen] = GENMALLOC(2
+ * sizeof(uint64_t *));
+ tarray[fuzzer_arg_array[fieldptr].contlen][0] = vecinput[0];
+ tarray[fuzzer_arg_array[fieldptr].contlen][1] = vecinput[1];
+ for (int i = 0; i < fuzzer_arg_array[fieldptr].contlen; i++) {
+ GENFREE(fuzzer_arg_array[fieldptr].contval[i]);
+ }
+ GENFREE(fuzzer_arg_array[fieldptr].contval);
+ fuzzer_arg_array[fieldptr].contval = tarray;
+ int *tarraysingle;
+ tarraysingle =
+ GENMALLOC((1 + fuzzer_arg_array[fieldptr].contlen) * sizeof(int *));
+ for (int i = 0; i < fuzzer_arg_array[fieldptr].contlen; i++) {
+ tarraysingle[i] = fuzzer_arg_array[fieldptr].contvallen[i];
+ }
+ tarraysingle[fuzzer_arg_array[fieldptr].contlen] = 2;
+ GENFREE(fuzzer_arg_array[fieldptr].contvallen);
+ fuzzer_arg_array[fieldptr].contvallen = tarraysingle;
+ tarraysingle = GENMALLOC((1 + fuzzer_arg_array[fieldptr].contlen)
+ * sizeof(int *));
+ for (int i = 0; i < fuzzer_arg_array[fieldptr].contlen; i++) {
+ tarraysingle[i] = fuzzer_arg_array[fieldptr].conttype[i];
+ }
+ tarraysingle[fuzzer_arg_array[fieldptr].contlen] = contype;
+ GENFREE(fuzzer_arg_array[fieldptr].conttype);
+ fuzzer_arg_array[fieldptr].conttype = tarraysingle;
+ fuzzer_arg_array[fieldptr].contlen++;
+ }
+ if (mode == FUZZER_CONSTRAINT_EXCMODE) {
+ for (int i = 0; i < fuzzer_arg_array[fieldptr].contlen; i++) {
+ GENFREE(fuzzer_arg_array[fieldptr].contval[i]);
+ }
+ GENFREE(fuzzer_arg_array[fieldptr].contval);
+ GENFREE(fuzzer_arg_array[fieldptr].contvallen);
+ GENFREE(fuzzer_arg_array[fieldptr].conttype);
+ fuzzer_arg_array[fieldptr].contval = GENMALLOC(1 * sizeof(uint64_t **));
+ fuzzer_arg_array[fieldptr].contval[0] = GENMALLOC(2 * sizeof(uint64_t *));
+ fuzzer_arg_array[fieldptr].contval[0][0] = vecinput[0];
+ fuzzer_arg_array[fieldptr].contval[0][1] = vecinput[1];
+ fuzzer_arg_array[fieldptr].contvallen = GENMALLOC(1 * sizeof(int *));
+ fuzzer_arg_array[fieldptr].contvallen[0] = 2;
+ fuzzer_arg_array[fieldptr].contlen = 1;
+ fuzzer_arg_array[fieldptr].conttype = GENMALLOC(1 * sizeof(int *));
+ fuzzer_arg_array[fieldptr].conttype[0] = contype;
+ }
+ }
+ }
+ if (contype == FUZZER_CONSTRAINT_VECTOR) {
+ if (veclen < 2) {
+ printf("vector length to constraint for vector is not large enough");
+ printf(" %d", veclen);
+ panic();
+ }
+ if (vecinput == NULL) {
+ printf("vector input to constraint vector is not defined\n");
+ panic();
+ }
+ if (fuzzer_arg_array[fieldptr].contval == NULL) {
+ fuzzer_arg_array[fieldptr].contval = GENMALLOC(1 * sizeof(uint64_t **));
+ fuzzer_arg_array[fieldptr].contval[0] = GENMALLOC(veclen * sizeof(uint64_t *));
+ for (int i = 0; i < veclen; i++) {
+ fuzzer_arg_array[fieldptr].contval[0][i] = vecinput[i];
+ }
+ fuzzer_arg_array[fieldptr].contvallen = GENMALLOC(1 * sizeof(int *));
+ fuzzer_arg_array[fieldptr].contvallen[0] = veclen;
+ fuzzer_arg_array[fieldptr].contlen = 1;
+ fuzzer_arg_array[fieldptr].conttype = GENMALLOC(1 * sizeof(int *));
+ fuzzer_arg_array[fieldptr].conttype[0] = contype;
+
+ } else {
+ if (mode == FUZZER_CONSTRAINT_ACCMODE) {
+ for (int i = 0; i < fuzzer_arg_array[fieldptr].contlen; i++) {
+ if (fuzzer_arg_array[fieldptr].conttype[i] ==
+ FUZZER_CONSTRAINT_VECTOR) {
+ if (fuzzer_arg_array[fieldptr].contvallen[i] == veclen) {
+ int fne = 0;
+ for (int j = 0; j <
+ fuzzer_arg_array[fieldptr].contvallen[i]; j++) {
+ if (fuzzer_arg_array[fieldptr].contval
+ [i][j] != vecinput[j]) {
+ fne = 1;
+ }
+ }
+ if (fne == 0) {
+ return;
+ }
+ }
+ }
+ }
+ uint64_t **tarray;
+
+ tarray = GENMALLOC((1 + fuzzer_arg_array[fieldptr].contlen)
+ * sizeof(uint64_t **));
+ for (int i = 0; i < fuzzer_arg_array[fieldptr].contlen; i++) {
+ tarray[i] = GENMALLOC(fuzzer_arg_array[fieldptr].contvallen
+ [i] * sizeof(uint64_t *));
+ for (int k = 0; k < fuzzer_arg_array[fieldptr].contvallen[i]; k++) {
+ tarray[i][k] = fuzzer_arg_array[fieldptr].contval[i][k];
+ }
+ }
+ tarray[fuzzer_arg_array[fieldptr].contlen] =
+ GENMALLOC(veclen * sizeof(uint64_t *));
+ for (int i = 0; i < veclen; i++) {
+ tarray[fuzzer_arg_array[fieldptr].contlen][i] = vecinput[i];
+ }
+ for (int i = 0; i < fuzzer_arg_array[fieldptr].contlen; i++) {
+ GENFREE(fuzzer_arg_array[fieldptr].contval[i]);
+ }
+ GENFREE(fuzzer_arg_array[fieldptr].contval);
+ fuzzer_arg_array[fieldptr].contval = tarray;
+ int *tarraysingle;
+ tarraysingle = GENMALLOC((1 + fuzzer_arg_array[fieldptr].contlen)
+ * sizeof(int *));
+ for (int i = 0; i < fuzzer_arg_array[fieldptr].contlen; i++) {
+ tarraysingle[i] = fuzzer_arg_array[fieldptr].contvallen[i];
+ }
+ tarraysingle[fuzzer_arg_array[fieldptr].contlen] = veclen;
+ GENFREE(fuzzer_arg_array[fieldptr].contvallen);
+ fuzzer_arg_array[fieldptr].contvallen = tarraysingle;
+ tarraysingle = GENMALLOC((1 + fuzzer_arg_array[fieldptr].contlen)
+ * sizeof(int *));
+ for (int i = 0; i < fuzzer_arg_array[fieldptr].contlen; i++) {
+ tarraysingle[i] = fuzzer_arg_array[fieldptr].conttype[i];
+ }
+ tarraysingle[fuzzer_arg_array[fieldptr].contlen] = contype;
+ GENFREE(fuzzer_arg_array[fieldptr].conttype);
+ fuzzer_arg_array[fieldptr].conttype = tarraysingle;
+ fuzzer_arg_array[fieldptr].contlen++;
+ }
+ if (mode == FUZZER_CONSTRAINT_EXCMODE) {
+ for (int i = 0; i < fuzzer_arg_array[fieldptr].contlen; i++) {
+ GENFREE(fuzzer_arg_array[fieldptr].contval[i]);
+ }
+ GENFREE(fuzzer_arg_array[fieldptr].contval);
+ GENFREE(fuzzer_arg_array[fieldptr].contvallen);
+ GENFREE(fuzzer_arg_array[fieldptr].conttype);
+ fuzzer_arg_array[fieldptr].contval = GENMALLOC(1 * sizeof(uint64_t **));
+ fuzzer_arg_array[fieldptr].contval[0] = GENMALLOC(veclen
+ * sizeof(uint64_t *));
+ for (int i = 0; i < veclen; i++) {
+ fuzzer_arg_array[fieldptr].contval[0][i] = vecinput[i];
+ }
+ fuzzer_arg_array[fieldptr].contvallen = GENMALLOC(1 * sizeof(int *));
+ fuzzer_arg_array[fieldptr].contvallen[0] = veclen;
+ fuzzer_arg_array[fieldptr].contlen = 1;
+ fuzzer_arg_array[fieldptr].conttype = GENMALLOC(1 * sizeof(int *));
+ fuzzer_arg_array[fieldptr].conttype[0] = contype;
+ }
+ }
+ }
+}
+
+/*******************************************************
+* Generate the uncondition(no constraint)
+* fields in the SMC call
+*******************************************************/
+
+uint64_t generate_field_uncon(int smccall, int rsel)
+{
+ uint64_t shiftreg = 0;
+ uint64_t resreg = 0;
+ int fieldptr = 0;
+ int argptr = fuzzer_arg_array_start[smccall] + rsel;
+
+ for (int i = 0; i <= (fuzzer_arg_array_lst[argptr].arg_span[1] -
+ fuzzer_arg_array_lst[argptr].arg_span[0]); i++) {
+ fieldptr = fuzzer_arg_array_lst[argptr].arg_span[0] + i;
+ shiftreg = shiftlft((rand() % shiftlft(1, fuzzer_arg_array[fieldptr].bitw)),
+ fuzzer_arg_array[fieldptr].bitst);
+ resreg = resreg | shiftreg;
+ }
+ return resreg;
+}
+
+uint64_t generate_field_con(int smccall, int rsel)
+{
+ uint64_t shiftreg = 0;
+ uint64_t resreg = 0;
+ int fieldptr = 0;
+ int nullstat = 0;
+ int argptr = fuzzer_arg_array_start[smccall] + rsel;
+
+ for (int i = 0; i <= (fuzzer_arg_array_lst[argptr].arg_span[1] -
+ fuzzer_arg_array_lst[argptr].arg_span[0]); i++) {
+ fieldptr = fuzzer_arg_array_lst[argptr].arg_span[0] + i;
+ nullstat = 0;
+ if (fuzzer_arg_array[fieldptr].contval == NULL) {
+ if (fuzzer_arg_array[fieldptr].defval >
+ (shiftlft(1, fuzzer_arg_array[fieldptr].bitw) - 1)) {
+ printf("Default constraint will not fit inside bitfield %llx %llx\n",
+ fuzzer_arg_array[fieldptr].defval,
+ (shiftlft(1, fuzzer_arg_array[fieldptr].bitw) - 1));
+ panic();
+ } else {
+ shiftreg = shiftlft(fuzzer_arg_array[fieldptr].defval,
+ fuzzer_arg_array[fieldptr].bitst);
+ resreg = resreg | shiftreg;
+ }
+ nullstat = 1;
+ } else if (fuzzer_arg_array[fieldptr].contval[0] == NULL) {
+ if (fuzzer_arg_array[fieldptr].defval >
+ (shiftlft(1, fuzzer_arg_array[fieldptr].bitw) - 1)) {
+ printf("Default constraint will not fit inside bitfield %llx %llx\n",
+ fuzzer_arg_array[fieldptr].defval,
+ (shiftlft(1, fuzzer_arg_array[fieldptr].bitw) - 1));
+ panic();
+ } else {
+ shiftreg = shiftlft(fuzzer_arg_array[fieldptr].defval,
+ fuzzer_arg_array[fieldptr].bitst);
+ resreg = resreg | shiftreg;
+ }
+ nullstat = 1;
+ }
+ if (nullstat == 0) {
+ int selcon = rand() % (fuzzer_arg_array[fieldptr].contlen);
+
+ if (fuzzer_arg_array[fieldptr].conttype[selcon] == FUZZER_CONSTRAINT_SVALUE) {
+ if (fuzzer_arg_array[fieldptr].contval[selcon][0] >
+ ((shiftlft(1, fuzzer_arg_array[fieldptr].bitw)) - 1)) {
+ printf("Constraint will not fit inside bitfield %llx %llx\n",
+ fuzzer_arg_array[fieldptr].contval[selcon][0],
+ ((shiftlft(1, fuzzer_arg_array[fieldptr].bitw)) - 1));
+ panic();
+ } else {
+ shiftreg = shiftlft(fuzzer_arg_array[fieldptr].contval[selcon][0],
+ fuzzer_arg_array[fieldptr].bitst);
+ resreg = resreg | shiftreg;
+ }
+ }
+
+ if (fuzzer_arg_array[fieldptr].conttype[selcon] == FUZZER_CONSTRAINT_RANGE) {
+ uint64_t maxn = shiftlft(1, fuzzer_arg_array[fieldptr].bitw);
+
+ if ((fuzzer_arg_array[fieldptr].contval[selcon][0] >
+ ((maxn) - 1)) || ((fuzzer_arg_array[fieldptr].contval[selcon][1] >
+ ((maxn) - 1)))) {
+ if (fuzzer_arg_array[fieldptr].contval[selcon][0] >
+ ((maxn) - 1)) {
+ printf("Constraint will not fit inside bitfield %llx %llx\n",
+ fuzzer_arg_array[fieldptr].contval[selcon][0], ((maxn) - 1));
+ }
+ if (fuzzer_arg_array[fieldptr].contval[selcon][1] >
+ ((maxn) - 1)) {
+ printf("Constraint will not fit inside bitfield %llx %llx\n",
+ fuzzer_arg_array[fieldptr].contval[selcon][1], ((maxn) - 1));
+ }
+ panic();
+ } else {
+ shiftreg = shiftlft(((rand() %
+ (fuzzer_arg_array[fieldptr].contval[selcon][1] -
+ fuzzer_arg_array[fieldptr].contval[selcon][0] + 1)) +
+ fuzzer_arg_array[fieldptr].contval[selcon][0]),
+ fuzzer_arg_array[fieldptr].bitst);
+ resreg = resreg | shiftreg;
+ }
+ }
+
+ if (fuzzer_arg_array[fieldptr].conttype[selcon] == FUZZER_CONSTRAINT_VECTOR) {
+ for (int j = 0; j < fuzzer_arg_array[fieldptr].contvallen[selcon]; j++) {
+ if (fuzzer_arg_array[fieldptr].contval[selcon][j] >
+ ((shiftlft(1, fuzzer_arg_array[fieldptr].bitw)) - 1)) {
+ printf("Constraint will not fit inside bitfield");
+ printf(" %llx %llx\n",
+ fuzzer_arg_array[fieldptr].contval[selcon][j],
+ ((shiftlft(1, fuzzer_arg_array[fieldptr].bitw)) - 1));
+ panic();
+ }
+ }
+ shiftreg = shiftlft((fuzzer_arg_array[fieldptr].contval[selcon]
+ [(rand() % (fuzzer_arg_array[fieldptr].contvallen[selcon]))]),
+ fuzzer_arg_array[fieldptr].bitst);
+ resreg = resreg | shiftreg;
+ }
+ }
+ }
+ return resreg;
+}
+
+/*******************************************************
+* Generate the field arguments for constrained fields
+* for all sanity levels
+*******************************************************/
+
+struct inputparameters generate_args(int smccall, int sanity)
+{
+ if ((smccall > MAX_SMC_CALLS) || (smccall < 0)) {
+ printf("generate args SMC call is out of bounds\n");
+ panic();
+ }
+ if ((sanity > SANITY_LEVEL_3) || (sanity < 0)) {
+ printf("generate args sanity level is out of bounds\n");
+ panic();
+ }
+ struct inputparameters nparam;
+
+ nparam.x1 = 1;
+ if (sanity == SANITY_LEVEL_0) {
+ for (int i = 0; i < fuzzer_arg_array_range[smccall]; i++) {
+ switch (i) {
+ case 0: {
+ nparam.x1 = rand64bit();
+ break;
+ }
+ case 1: {
+ nparam.x2 = rand64bit();
+ break;
+ }
+ case 2: {
+ nparam.x3 = rand64bit();
+ break;
+ }
+ case 3: {
+ nparam.x4 = rand64bit();
+ break;
+ }
+ case 4: {
+ nparam.x5 = rand64bit();
+ break;
+ }
+ case 5: {
+ nparam.x6 = rand64bit();
+ break;
+ }
+ case 6: {
+ nparam.x7 = rand64bit();
+ break;
+ }
+ case 7: {
+ nparam.x8 = rand64bit();
+ break;
+ }
+ case 8: {
+ nparam.x9 = rand64bit();
+ break;
+ }
+ case 9: {
+ nparam.x10 = rand64bit();
+ break;
+ }
+ case 10: {
+ nparam.x11 = rand64bit();
+ break;
+ }
+ case 11: {
+ nparam.x12 = rand64bit();
+ break;
+ }
+ case 12: {
+ nparam.x13 = rand64bit();
+ break;
+ }
+ case 13: {
+ nparam.x14 = rand64bit();
+ break;
+ }
+ case 14: {
+ nparam.x15 = rand64bit();
+ break;
+ }
+ case 15: {
+ nparam.x16 = rand64bit();
+ break;
+ }
+ case 16: {
+ nparam.x17 = rand64bit();
+ break;
+ }
+ }
+ }
+ }
+ if (sanity == SANITY_LEVEL_1) {
+ int selreg = rand() % (fuzzer_arg_array_range[smccall] + 1);
+ for (int i = 0; i < fuzzer_arg_array_range[smccall]; i++) {
+ switch (i) {
+ case 0: {
+ if (selreg == 0) {
+ nparam.x1 = generate_field_uncon(smccall, i);
+ } else {
+ nparam.x1 = rand64bit();
+ }
+ break;
+ }
+ case 1: {
+ if (selreg == 1) {
+ nparam.x2 = generate_field_uncon(smccall, i);
+ } else {
+ nparam.x2 = rand64bit();
+ }
+ break;
+ }
+ case 2: {
+ if (selreg == 2) {
+ nparam.x3 = generate_field_uncon(smccall, i);
+ } else {
+ nparam.x3 = rand64bit();
+ }
+ break;
+ }
+ case 3: {
+ if (selreg == 3) {
+ nparam.x4 = generate_field_uncon(smccall, i);
+ } else {
+ nparam.x4 = rand64bit();
+ }
+ break;
+ }
+ case 4: {
+ if (selreg == 4) {
+ nparam.x5 = generate_field_uncon(smccall, i);
+ } else {
+ nparam.x5 = rand64bit();
+ }
+ break;
+ }
+ case 5: {
+ if (selreg == 5) {
+ nparam.x6 = generate_field_uncon(smccall, i);
+ } else {
+ nparam.x6 = rand64bit();
+ }
+ break;
+ }
+ case 6: {
+ if (selreg == 6) {
+ nparam.x7 = generate_field_uncon(smccall, i);
+ } else {
+ nparam.x7 = rand64bit();
+ }
+ break;
+ }
+ case 7: {
+ if (selreg == 7) {
+ nparam.x8 = generate_field_uncon(smccall, i);
+ } else {
+ nparam.x8 = rand64bit();
+ }
+ break;
+ }
+ case 8: {
+ if (selreg == 8) {
+ nparam.x9 = generate_field_uncon(smccall, i);
+ } else {
+ nparam.x9 = rand64bit();
+ }
+ break;
+ }
+ case 9: {
+ if (selreg == 9) {
+ nparam.x10 = generate_field_uncon(smccall, i);
+ } else {
+ nparam.x10 = rand64bit();
+ }
+ break;
+ }
+ case 10: {
+ if (selreg == 10) {
+ nparam.x11 = generate_field_uncon(smccall, i);
+ } else {
+ nparam.x11 = rand64bit();
+ }
+ break;
+ }
+ case 11: {
+ if (selreg == 11) {
+ nparam.x12 = generate_field_uncon(smccall, i);
+ } else {
+ nparam.x12 = rand64bit();
+ }
+ break;
+ }
+ case 12: {
+ if (selreg == 12) {
+ nparam.x13 = generate_field_uncon(smccall, i);
+ } else {
+ nparam.x13 = rand64bit();
+ }
+ break;
+ }
+ case 13: {
+ if (selreg == 13) {
+ nparam.x14 = generate_field_uncon(smccall, i);
+ } else {
+ nparam.x14 = rand64bit();
+ }
+ break;
+ }
+ case 14: {
+ if (selreg == 14) {
+ nparam.x15 = generate_field_uncon(smccall, i);
+ } else {
+ nparam.x15 = rand64bit();
+ }
+ break;
+ }
+ case 15: {
+ if (selreg == 15) {
+ nparam.x16 = generate_field_uncon(smccall, i);
+ } else {
+ nparam.x16 = rand64bit();
+ }
+ break;
+ }
+ case 16: {
+ if (selreg == 16) {
+ nparam.x17 = generate_field_uncon(smccall, i);
+ } else {
+ nparam.x17 = rand64bit();
+ }
+ break;
+ }
+ }
+ }
+ }
+ if (sanity == SANITY_LEVEL_2) {
+ for (int i = 0; i < fuzzer_arg_array_range[smccall]; i++) {
+ switch (i) {
+ case 0: {
+ nparam.x1 = generate_field_uncon(smccall, i);
+ break;
+ }
+ case 1: {
+ nparam.x2 = generate_field_uncon(smccall, i);
+ break;
+ }
+ case 2: {
+ nparam.x3 = generate_field_uncon(smccall, i);
+ break;
+ }
+ case 3: {
+ nparam.x4 = generate_field_uncon(smccall, i);
+ break;
+ }
+ case 4: {
+ nparam.x5 = generate_field_uncon(smccall, i);
+ break;
+ }
+ case 5: {
+ nparam.x6 = generate_field_uncon(smccall, i);
+ break;
+ }
+ case 6: {
+ nparam.x7 = generate_field_uncon(smccall, i);
+ break;
+ }
+ case 7: {
+ nparam.x8 = generate_field_uncon(smccall, i);
+ break;
+ }
+ case 8: {
+ nparam.x9 = generate_field_uncon(smccall, i);
+ break;
+ }
+ case 9: {
+ nparam.x10 = generate_field_uncon(smccall, i);
+ break;
+ }
+ case 10: {
+ nparam.x11 = generate_field_uncon(smccall, i);
+ break;
+ }
+ case 11: {
+ nparam.x12 = generate_field_uncon(smccall, i);
+ break;
+ }
+ case 12: {
+ nparam.x13 = generate_field_uncon(smccall, i);
+ break;
+ }
+ case 13: {
+ nparam.x14 = generate_field_uncon(smccall, i);
+ break;
+ }
+ case 14: {
+ nparam.x15 = generate_field_uncon(smccall, i);
+ break;
+ }
+ case 15: {
+ nparam.x16 = generate_field_uncon(smccall, i);
+ break;
+ }
+ case 16: {
+ nparam.x17 = generate_field_uncon(smccall, i);
+ break;
+ }
+ }
+ }
+ }
+ if (sanity == SANITY_LEVEL_3) {
+ for (int i = 0; i < fuzzer_arg_array_range[smccall]; i++) {
+ switch (i) {
+ case 0: {
+ nparam.x1 = generate_field_con(smccall, i);
+ break;
+ }
+ case 1: {
+ nparam.x2 = generate_field_con(smccall, i);
+ break;
+ }
+ case 2: {
+ nparam.x3 = generate_field_con(smccall, i);
+ break;
+ }
+ case 3: {
+ nparam.x4 = generate_field_con(smccall, i);
+ break;
+ }
+ case 4: {
+ nparam.x5 = generate_field_con(smccall, i);
+ break;
+ }
+ case 5: {
+ nparam.x6 = generate_field_con(smccall, i);
+ break;
+ }
+ case 6: {
+ nparam.x7 = generate_field_con(smccall, i);
+ break;
+ }
+ case 7: {
+ nparam.x8 = generate_field_con(smccall, i);
+ break;
+ }
+ case 8: {
+ nparam.x9 = generate_field_con(smccall, i);
+ break;
+ }
+ case 9: {
+ nparam.x10 = generate_field_con(smccall, i);
+ break;
+ }
+ case 10: {
+ nparam.x11 = generate_field_con(smccall, i);
+ break;
+ }
+ case 11: {
+ nparam.x12 = generate_field_con(smccall, i);
+ break;
+ }
+ case 12: {
+ nparam.x13 = generate_field_con(smccall, i);
+ break;
+ }
+ case 13: {
+ nparam.x14 = generate_field_con(smccall, i);
+ break;
+ }
+ case 14: {
+ nparam.x15 = generate_field_con(smccall, i);
+ break;
+ }
+ case 15: {
+ nparam.x16 = generate_field_con(smccall, i);
+ break;
+ }
+ case 16: {
+ nparam.x17 = generate_field_con(smccall, i);
+ break;
+ }
+ }
+ }
+ }
+ #ifdef SMC_FUZZER_DEBUG
+ print_smccall(smccall, nparam);
+ #endif
+ return nparam;
+}
+
+/*******************************************************
+* Get generated value from fuzzer for a given field
+*******************************************************/
+
+uint64_t get_generated_value(int fieldnameptr, struct inputparameters inp)
+{
+ uint64_t xval = 0;
+ int argdef = fuzzer_fieldarg[fieldnameptr];
+ int fieldname = fuzzer_fieldfld[fieldnameptr];
+ int fieldptr = fuzzer_arg_array_lst[argdef].arg_span[0] + fieldname;
+
+ switch(fuzzer_arg_array[fieldptr].regnum) {
+ case 1: {
+ xval = shiftrht(inp.x1, fuzzer_arg_array[fieldptr].bitst) &
+ ((shiftlft(1, fuzzer_arg_array[fieldptr].bitw)) - 1);
+ return xval;
+ }
+ case 2: {
+ xval = shiftrht(inp.x2, fuzzer_arg_array[fieldptr].bitst) &
+ ((shiftlft(1, fuzzer_arg_array[fieldptr].bitw)) - 1);
+ return xval;
+ }
+ case 3: {
+ xval = shiftrht(inp.x3, fuzzer_arg_array[fieldptr].bitst) &
+ ((shiftlft(1, fuzzer_arg_array[fieldptr].bitw)) - 1);
+ return xval;
+ }
+ case 4: {
+ xval = shiftrht(inp.x4, fuzzer_arg_array[fieldptr].bitst) &
+ ((shiftlft(1, fuzzer_arg_array[fieldptr].bitw)) - 1);
+ return xval;
+ }
+ case 5: {
+ xval = shiftrht(inp.x5, fuzzer_arg_array[fieldptr].bitst) &
+ ((shiftlft(1, fuzzer_arg_array[fieldptr].bitw)) - 1);
+ return xval;
+ }
+ case 6: {
+ xval = shiftrht(inp.x6, fuzzer_arg_array[fieldptr].bitst) &
+ ((shiftlft(1, fuzzer_arg_array[fieldptr].bitw)) - 1);
+ return xval;
+ }
+ case 7: {
+ xval = shiftrht(inp.x7, fuzzer_arg_array[fieldptr].bitst) &
+ ((shiftlft(1, fuzzer_arg_array[fieldptr].bitw)) - 1);
+ return xval;
+ }
+ case 8: {
+ xval = shiftrht(inp.x8, fuzzer_arg_array[fieldptr].bitst) &
+ ((shiftlft(1, fuzzer_arg_array[fieldptr].bitw)) - 1);
+ return xval;
+ }
+ case 9: {
+ xval = shiftrht(inp.x9, fuzzer_arg_array[fieldptr].bitst) &
+ ((shiftlft(1, fuzzer_arg_array[fieldptr].bitw)) - 1);
+ return xval;
+ }
+ case 10: {
+ xval = shiftrht(inp.x10, fuzzer_arg_array[fieldptr].bitst) &
+ ((shiftlft(1, fuzzer_arg_array[fieldptr].bitw)) - 1);
+ return xval;
+ }
+ case 11: {
+ xval = shiftrht(inp.x11, fuzzer_arg_array[fieldptr].bitst) &
+ ((shiftlft(1, fuzzer_arg_array[fieldptr].bitw)) - 1);
+ return xval;
+ }
+ case 12: {
+ xval = shiftrht(inp.x12, fuzzer_arg_array[fieldptr].bitst) &
+ ((shiftlft(1, fuzzer_arg_array[fieldptr].bitw)) - 1);
+ return xval;
+ }
+ case 13: {
+ xval = shiftrht(inp.x13, fuzzer_arg_array[fieldptr].bitst) &
+ ((shiftlft(1, fuzzer_arg_array[fieldptr].bitw)) - 1);
+ return xval;
+ }
+ case 14: {
+ xval = shiftrht(inp.x14, fuzzer_arg_array[fieldptr].bitst) &
+ ((shiftlft(1, fuzzer_arg_array[fieldptr].bitw)) - 1);
+ return xval;
+ }
+ case 15: {
+ xval = shiftrht(inp.x15, fuzzer_arg_array[fieldptr].bitst) &
+ ((shiftlft(1, fuzzer_arg_array[fieldptr].bitw)) - 1);
+ return xval;
+ }
+ case 16: {
+ xval = shiftrht(inp.x16, fuzzer_arg_array[fieldptr].bitst) &
+ ((shiftlft(1, fuzzer_arg_array[fieldptr].bitw)) - 1);
+ return xval;
+ }
+ case 17: {
+ xval = shiftrht(inp.x17, fuzzer_arg_array[fieldptr].bitst) &
+ ((shiftlft(1, fuzzer_arg_array[fieldptr].bitw)) - 1);
+ return xval;
+ }
+ }
+ return xval;
+}
+
+/*******************************************************
+* Print the values from a generated SMC call from fuzzer
+*******************************************************/
+
+void print_smccall(int smccall, struct inputparameters inp)
+{
+ if ((smccall > MAX_SMC_CALLS) || (smccall < 0)) {
+ printf("generate args SMC call is out of bounds\n");
+ panic();
+ }
+ int argptr = fuzzer_arg_array_start[smccall];
+ int fieldptr = fuzzer_arg_array_lst[fuzzer_arg_array_start[smccall]].arg_span[0];
+
+ printf("%s\n", fuzzer_arg_array[fieldptr].smcname);
+ for (int i = 0; i < (fuzzer_arg_array_range[smccall]); i++) {
+ fieldptr = fuzzer_arg_array_lst[argptr + i].arg_span[0];
+ printf("argument: %s\n", fuzzer_arg_array[fieldptr].smcargname);
+ for (int j = fieldptr; j <= ((fuzzer_arg_array_lst[argptr + i].arg_span[1] -
+ fuzzer_arg_array_lst[argptr + i].arg_span[0]) + fieldptr); j++) {
+ printf("%s = %llx\n", fuzzer_arg_array[j].bnames,
+ get_generated_value(j, inp));
+ }
+ }
+ printf("\n\n");
+}
diff --git a/smc_fuzz/src/randsmcmod.c b/smc_fuzz/src/randsmcmod.c
index a86feb6..1cbf44a 100644
--- a/smc_fuzz/src/randsmcmod.c
+++ b/smc_fuzz/src/randsmcmod.c
@@ -4,20 +4,22 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include "fifo3d.h"
+#include "nfifo.h"
+
#include <arch_helpers.h>
#include <debug.h>
#include <drivers/arm/private_timer.h>
#include <events.h>
-#include "fifo3d.h"
-#include "nfifo.h"
#include <libfdt.h>
-
#include <plat_topology.h>
#include <power_management.h>
#include <tftf_lib.h>
+
extern char _binary___dtb_start[];
-extern void runtestfunction(int funcid);
+extern void runtestfunction(int funcid, struct memmod *mmod);
+extern void init_input_arg_struct(void);
struct memmod tmod __aligned(65536) __section("smcfuzz");
static int cntndarray;
@@ -233,9 +235,9 @@
(fdt32_to_cpu(fhd.off_dt_strings) +
fdt32_to_cpu(pv.nameoff)), cset);
if (strcmp(cset, "bias") == 0) {
- rval = *((unsigned int *)dtb);
+ unsigned int bval = *((unsigned int *)dtb);
dtb += sizeof(unsigned int);
- push_3dfifo_bias(&f3d, fdt32_to_cpu(rval));
+ push_3dfifo_bias(&f3d, fdt32_to_cpu(bval));
bias_count++;
if (bintnode == 1U) {
fnode = 0U;
@@ -494,7 +496,10 @@
int selent = tlnode->biasarray[nch];
if (tlnode->norcall[selent] == 0) {
- runtestfunction(tlnode->snameid[selent]);
+ #ifdef SMC_FUZZER_DEBUG
+ printf("the name of the SMC call is %s\n", tlnode->snames[selent]);
+ #endif
+ runtestfunction(tlnode->snameid[selent], mmod);
nd = 1;
} else {
tlnode = &tlnode->treenodes[selent];
diff --git a/smc_fuzz/src/runtestfunction_helpers.c b/smc_fuzz/src/runtestfunction_helpers.c
index c3b2cca..50bf395 100644
--- a/smc_fuzz/src/runtestfunction_helpers.c
+++ b/smc_fuzz/src/runtestfunction_helpers.c
@@ -5,14 +5,14 @@
*/
#include <sdei_fuzz_helper.h>
+#include "smcmalloc.h"
#include <tsp_fuzz_helper.h>
-
/*
* Invoke the SMC call based on the function name specified.
*/
-void runtestfunction(int funcid)
+void runtestfunction(int funcid, struct memmod *mmod)
{
- run_sdei_fuzz(funcid);
+ run_sdei_fuzz(funcid, mmod);
run_tsp_fuzz(funcid);
}
diff --git a/smc_fuzz/src/sdei_fuzz_helper.c b/smc_fuzz/src/sdei_fuzz_helper.c
index 1d22335..cbba482 100644
--- a/smc_fuzz/src/sdei_fuzz_helper.c
+++ b/smc_fuzz/src/sdei_fuzz_helper.c
@@ -4,9 +4,16 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <arg_struct_def.h>
+#include "constraint.h"
#include <fuzz_names.h>
#include <sdei_fuzz_helper.h>
+#define INTERRUPT_BIND_INT_LOWVAL 170
+#define INTERRUPT_BIND_INT_HIGHVAL 200
+
+int stbev = 0;
+
/*
* SDEI function that has no arguments
*/
@@ -24,7 +31,11 @@
*/
void tftf_test_sdei_singlearg(int64_t (*sdei_func)(uint64_t), char *funcstr)
{
- int64_t ret = (*sdei_func)(0);
+ struct sdei_intr_ctx intr_ctx;
+ int bev;
+
+ bev = sdei_interrupt_bind(tftf_get_timer_irq(), &intr_ctx);
+ int64_t ret = (*sdei_func)(bev);
if (ret < 0) {
tftf_testcase_printf("%s failed: 0x%llx\n", funcstr, ret);
@@ -34,7 +45,7 @@
/*
* SDEI function called from fuzzer
*/
-void run_sdei_fuzz(int funcid)
+void run_sdei_fuzz(int funcid, struct memmod *mmod)
{
if (funcid == sdei_version_funcid) {
long long ret = sdei_version();
@@ -47,10 +58,33 @@
tftf_test_sdei_noarg(sdei_pe_unmask, "sdei_pe_unmuask");
} else if (funcid == sdei_pe_mask_funcid) {
tftf_test_sdei_noarg(sdei_pe_mask, "sdei_pe_mask");
+ } else if (funcid == sdei_interrupt_bind_funcid) {
+ struct sdei_intr_ctx intr_ctx;
+ uint64_t inputbind[2] = {INTERRUPT_BIND_INT_LOWVAL, INTERRUPT_BIND_INT_HIGHVAL};
+
+ setconstraint(FUZZER_CONSTRAINT_RANGE, inputbind, 2,
+ SDEI_INTERRUPT_BIND_CALL_ARG1_INUM, mmod, FUZZER_CONSTRAINT_EXCMODE);
+
+ struct inputparameters inp = generate_args(SDEI_INTERRUPT_BIND_CALL, SMC_FUZZ_SANITY_LEVEL);
+
+ stbev = sdei_interrupt_bind(inp.x1, &intr_ctx);
+
} else if (funcid == sdei_event_status_funcid) {
+ int64_t ret = sdei_event_status(stbev);
+
+ if (ret < 0) {
+ tftf_testcase_printf("sdei_event_status failed: 0x%llx %d\n", ret, stbev);
+ }
+
tftf_test_sdei_singlearg((int64_t (*)(uint64_t))sdei_event_status,
"sdei_event_status");
} else if (funcid == sdei_event_signal_funcid) {
+ int64_t ret = sdei_event_signal(read_mpidr_el1());
+
+ if (ret < 0) {
+ tftf_testcase_printf("sdei_event_status failed: 0x%llx\n", ret);
+ }
+
tftf_test_sdei_singlearg(sdei_event_signal, "sdei_event_signal");
} else if (funcid == sdei_private_reset_funcid) {
tftf_test_sdei_noarg(sdei_private_reset, "sdei_private_reset");