blob: 7e4c4b5c11c4d3b7e863d804ae14dc8a36866f0d [file] [log] [blame]
/*
* 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");
}