diff options
author | Alon Zakai <alonzakai@gmail.com> | 2016-05-06 10:28:47 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2016-05-06 17:52:36 -0700 |
commit | a2cfae4c54ba79d7e8b348da10c77840ca934595 (patch) | |
tree | c9dfdc133fdd77b5a62d2e9bab8f32c07c0ae5ab /test/example/relooper-fuzz.c | |
parent | ffb9e4b9cfac5091dfe19b9b5215c43bd0f98e72 (diff) | |
download | binaryen-a2cfae4c54ba79d7e8b348da10c77840ca934595.tar.gz binaryen-a2cfae4c54ba79d7e8b348da10c77840ca934595.tar.bz2 binaryen-a2cfae4c54ba79d7e8b348da10c77840ca934595.zip |
add a fuzzer for the relooper through the C API
Diffstat (limited to 'test/example/relooper-fuzz.c')
-rw-r--r-- | test/example/relooper-fuzz.c | 267 |
1 files changed, 267 insertions, 0 deletions
diff --git a/test/example/relooper-fuzz.c b/test/example/relooper-fuzz.c new file mode 100644 index 000000000..ba9bcb3ed --- /dev/null +++ b/test/example/relooper-fuzz.c @@ -0,0 +1,267 @@ + + +#include <assert.h> +#include <stdio.h> + +#include "binaryen-c.h" + +// globals: address 4 is index +// decisions are at address 8+ + +int main() { + BinaryenModuleRef module = BinaryenModuleCreate(); + + // check() + + // if the end, halt + BinaryenExpressionRef halter = BinaryenIf(module, + BinaryenBinary(module, + BinaryenEq(), + BinaryenLoad(module, 4, 0, 0, 0, BinaryenInt32(), BinaryenConst(module, BinaryenLiteralInt32(4))), + BinaryenConst(module, BinaryenLiteralInt32(4 * 27)) // jumps of 4 bytes + ), + BinaryenUnreachable(module), + NULL + ); + // increment index + BinaryenExpressionRef incer = BinaryenStore(module, + 4, 0, 0, + BinaryenConst(module, BinaryenLiteralInt32(4)), + BinaryenBinary(module, + BinaryenAdd(), + BinaryenLoad(module, 4, 0, 0, 0, BinaryenInt32(), BinaryenConst(module, BinaryenLiteralInt32(4))), + BinaryenConst(module, BinaryenLiteralInt32(4)) + ) + ); + + // optionally, print the return value + BinaryenExpressionRef args[] = { + BinaryenBinary(module, + BinaryenSub(), + BinaryenConst(module, BinaryenLiteralInt32(0)), + BinaryenLoad(module, + 4, 0, 4, 0, BinaryenInt32(), + BinaryenLoad(module, 4, 0, 0, 0, BinaryenInt32(), BinaryenConst(module, BinaryenLiteralInt32(4))) + ) + ) + }; + BinaryenExpressionRef debugger; + if (1) debugger = BinaryenCallImport(module, "print", args, 1, BinaryenNone()); + else debugger = BinaryenNop(module); + + // return the decision. need to subtract 4 that we just added, and add 8 since that's where we start, so overall offset 4 + BinaryenExpressionRef returner = BinaryenLoad(module, + 4, 0, 4, 0, BinaryenInt32(), + BinaryenLoad(module, 4, 0, 0, 0, BinaryenInt32(), BinaryenConst(module, BinaryenLiteralInt32(4))) + ); + BinaryenExpressionRef checkBodyList[] = { halter, incer, debugger, returner }; + BinaryenExpressionRef checkBody = BinaryenBlock(module, NULL, checkBodyList, sizeof(checkBodyList) / sizeof(BinaryenExpressionRef)); + BinaryenFunctionTypeRef i = BinaryenAddFunctionType(module, "i", BinaryenInt32(), NULL, 0); + BinaryenAddFunction(module, "check", i, NULL, 0, checkBody); + + // contents of main() begin here + + RelooperRef relooper = RelooperCreate(); + + + RelooperBlockRef b0; + { + BinaryenExpressionRef args[] = { BinaryenConst(module, BinaryenLiteralInt32(0)) }; + BinaryenExpressionRef list[] = { + BinaryenCallImport(module, "print", args, 1, BinaryenNone()), + BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0, BinaryenInt32())) + }; + b0 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2)); + } + + RelooperBlockRef b1; + { + BinaryenExpressionRef args[] = { BinaryenConst(module, BinaryenLiteralInt32(1)) }; + BinaryenExpressionRef list[] = { + BinaryenCallImport(module, "print", args, 1, BinaryenNone()), + BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0, BinaryenInt32())) + }; + b1 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2)); + } + + RelooperBlockRef b2; + { + BinaryenExpressionRef args[] = { BinaryenConst(module, BinaryenLiteralInt32(2)) }; + BinaryenExpressionRef list[] = { + BinaryenCallImport(module, "print", args, 1, BinaryenNone()), + BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0, BinaryenInt32())) + }; + b2 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2)); + } + + RelooperBlockRef b3; + { + BinaryenExpressionRef args[] = { BinaryenConst(module, BinaryenLiteralInt32(3)) }; + BinaryenExpressionRef list[] = { + BinaryenCallImport(module, "print", args, 1, BinaryenNone()), + BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0, BinaryenInt32())) + }; + b3 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2)); + } + + RelooperBlockRef b4; + { + BinaryenExpressionRef args[] = { BinaryenConst(module, BinaryenLiteralInt32(4)) }; + BinaryenExpressionRef list[] = { + BinaryenCallImport(module, "print", args, 1, BinaryenNone()), + BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0, BinaryenInt32())) + }; + b4 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2)); + } + + RelooperBlockRef b5; + { + BinaryenExpressionRef args[] = { BinaryenConst(module, BinaryenLiteralInt32(5)) }; + BinaryenExpressionRef list[] = { + BinaryenCallImport(module, "print", args, 1, BinaryenNone()), + BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0, BinaryenInt32())) + }; + b5 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2)); + } + + RelooperBlockRef b6; + { + BinaryenExpressionRef args[] = { BinaryenConst(module, BinaryenLiteralInt32(6)) }; + BinaryenExpressionRef list[] = { + BinaryenCallImport(module, "print", args, 1, BinaryenNone()), + BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0, BinaryenInt32())) + }; + b6 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2)); + } + + RelooperBlockRef b7; + { + BinaryenExpressionRef args[] = { BinaryenConst(module, BinaryenLiteralInt32(7)) }; + BinaryenExpressionRef list[] = { + BinaryenCallImport(module, "print", args, 1, BinaryenNone()), + BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0, BinaryenInt32())) + }; + b7 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2)); + } + + RelooperBlockRef b8; + { + BinaryenExpressionRef args[] = { BinaryenConst(module, BinaryenLiteralInt32(8)) }; + BinaryenExpressionRef list[] = { + BinaryenCallImport(module, "print", args, 1, BinaryenNone()), + BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0, BinaryenInt32())) + }; + b8 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2)); + } + + RelooperAddBranch(b0, b5, BinaryenBinary(module, + BinaryenEq(), + BinaryenBinary(module, + BinaryenRemU(), + BinaryenGetLocal(module, 0, BinaryenInt32()), + BinaryenConst(module, BinaryenLiteralInt32(2)) + ), + BinaryenConst(module, BinaryenLiteralInt32(0)) + ), NULL); + + RelooperAddBranch(b0, b8, NULL, NULL); + + RelooperAddBranch(b1, b5, NULL, NULL); + + RelooperAddBranch(b2, b5, NULL, NULL); + + RelooperAddBranch(b3, b5, BinaryenBinary(module, + BinaryenEq(), + BinaryenBinary(module, + BinaryenRemU(), + BinaryenGetLocal(module, 0, BinaryenInt32()), + BinaryenConst(module, BinaryenLiteralInt32(2)) + ), + BinaryenConst(module, BinaryenLiteralInt32(0)) + ), NULL); + + RelooperAddBranch(b3, b8, NULL, NULL); + + RelooperAddBranch(b4, b4, BinaryenBinary(module, + BinaryenEq(), + BinaryenBinary(module, + BinaryenRemU(), + BinaryenGetLocal(module, 0, BinaryenInt32()), + BinaryenConst(module, BinaryenLiteralInt32(3)) + ), + BinaryenConst(module, BinaryenLiteralInt32(0)) + ), NULL); + + RelooperAddBranch(b4, b5, BinaryenBinary(module, + BinaryenEq(), + BinaryenBinary(module, + BinaryenRemU(), + BinaryenGetLocal(module, 0, BinaryenInt32()), + BinaryenConst(module, BinaryenLiteralInt32(3)) + ), + BinaryenConst(module, BinaryenLiteralInt32(1)) + ), NULL); + + RelooperAddBranch(b4, b2, NULL, NULL); + + RelooperAddBranch(b5, b4, BinaryenBinary(module, + BinaryenEq(), + BinaryenBinary(module, + BinaryenRemU(), + BinaryenGetLocal(module, 0, BinaryenInt32()), + BinaryenConst(module, BinaryenLiteralInt32(2)) + ), + BinaryenConst(module, BinaryenLiteralInt32(0)) + ), NULL); + + RelooperAddBranch(b5, b5, NULL, NULL); + + RelooperAddBranch(b6, b6, NULL, NULL); + + RelooperAddBranch(b7, b8, NULL, NULL); + + RelooperAddBranch(b8, b4, NULL, NULL); + + BinaryenExpressionRef body = RelooperRenderAndDispose(relooper, b0, 1, module); + + int decisions[] = { 89, 12, 78, 149, 118, 179, 127, 80, 21, 34, 119, 98, 38, 29, 36, 147, 13, 55, 166, 16, 143, 52, 130, 150, 176, 91, 34 }; + int numDecisions = sizeof(decisions)/sizeof(int); + + BinaryenExpressionRef full[numDecisions + 1]; // write out all the decisions, then the body of the function + + for (int i = 0; i < numDecisions; i++) { + full[i] = BinaryenStore(module, + 4, 0, 0, + BinaryenConst(module, BinaryenLiteralInt32(8 + 4 * i)), + BinaryenConst(module, BinaryenLiteralInt32(decisions[i])) + ); + } + full[numDecisions] = body; + BinaryenExpressionRef all = BinaryenBlock(module, NULL, full, numDecisions + 1); + + BinaryenFunctionTypeRef v = BinaryenAddFunctionType(module, "v", BinaryenNone(), NULL, 0); + BinaryenType localTypes[] = { BinaryenInt32(), BinaryenInt32() }; // state, free-for-label + BinaryenFunctionRef theMain = BinaryenAddFunction(module, "main", v, localTypes, 2, all); + BinaryenSetStart(module, theMain); + + // import + + BinaryenType iparams[] = { BinaryenInt32() }; + BinaryenFunctionTypeRef vi = BinaryenAddFunctionType(module, "vi", BinaryenNone(), iparams, 1); + BinaryenAddImport(module, "print", "spectest", "print", vi); + + // memory + BinaryenSetMemory(module, 1, 1, "mem", NULL, NULL, NULL, 0); + + BinaryenModuleOptimize(module); + + assert(BinaryenModuleValidate(module)); + + // write it out + + BinaryenModulePrint(module); + + BinaryenModuleDispose(module); + + return 0; +} |