19
19
#include " ../../src/Utils/macros.h"
20
20
#include " ../../src/Utils/util.h"
21
21
#include " warduino/config.h"
22
+ #include " bigint.h"
22
23
23
24
// Constants
24
25
#define MAX_MODULE_SIZE (64 * 1024 * 1024 )
@@ -457,6 +458,85 @@ struct Model {
457
458
return count;
458
459
}
459
460
461
+ size_t max_fanout () {
462
+ size_t max = 0 ;
463
+ if (subpaths.size () > max) {
464
+ max = subpaths.size ();
465
+ }
466
+ for (Model path : subpaths) {
467
+ max = std::max (path.max_fanout (), max);
468
+ }
469
+ return max;
470
+ }
471
+
472
+ int min_fanout () {
473
+ int min = -1 ;
474
+ if (!subpaths.empty () && (min < 0 || subpaths.size () < min)) {
475
+ min = subpaths.size ();
476
+ }
477
+
478
+ for (Model path : subpaths) {
479
+ int val = path.min_fanout ();
480
+ if (val > 0 ) {
481
+ min = std::min (val, min);
482
+ }
483
+ }
484
+ return min;
485
+ }
486
+
487
+ BigInt::bigint prim_states (const std::string& prim) {
488
+ if (prim == " chip_analog_read" ) {
489
+ return 4096 ;
490
+ }
491
+ if (prim == " chip_digital_read" ) {
492
+ return 2 ;
493
+ }
494
+ }
495
+
496
+ BigInt::bigint max_states () {
497
+ BigInt::bigint max = 0 ;
498
+ for (auto model : subpaths) {
499
+ BigInt::bigint value = model.max_states (0 );
500
+ if (value > max) {
501
+ max = value;
502
+ }
503
+ }
504
+ return max;
505
+ }
506
+
507
+ BigInt::bigint max_states (size_t depth) {
508
+ // TODO: Maybe, maybe not, knock lock for example
509
+ /* if (subpaths.empty()) {
510
+ return 1;
511
+ }*/
512
+
513
+ BigInt::bigint v = prim_states (values[" x_" + std::to_string (depth)].primitive_origin );
514
+ BigInt::bigint max = v;
515
+ for (int i = 0 ; i < subpaths.size (); i++) {
516
+ BigInt::bigint value = v * subpaths[i].max_states (depth + 1 ); // Might overflow (Gesture-robot)
517
+ if (value > max) {
518
+ max = value;
519
+ }
520
+ }
521
+ return max;
522
+ }
523
+
524
+ void fanouts (std::vector<size_t > &fanout) {
525
+ if (subpaths.empty ()) {
526
+ return ;
527
+ }
528
+ fanout.emplace_back (subpaths.size ());
529
+ for (Model path : subpaths) {
530
+ path.fanouts (fanout);
531
+ }
532
+ }
533
+
534
+ float avg_fanout () {
535
+ std::vector<size_t > f;
536
+ fanouts (f);
537
+ return static_cast <float >(std::reduce (f.begin (), f.end ())) / static_cast <float >(f.size ());
538
+ }
539
+
460
540
nlohmann::json to_json () {
461
541
nlohmann::json graph;
462
542
graph[" paths" ] = to_json (0 );
@@ -506,7 +586,8 @@ z3::expr preconditions() {
506
586
return primitive_bounds;
507
587
}
508
588
509
- void run_concolic (const std::vector<std::string>& snapshot_messages, int max_instructions = 50 , int max_sym_vars = -1 , int max_iterations = -1 ) {
589
+ void run_concolic (const std::vector<std::string>& snapshot_messages, int max_instructions = 50 , int max_sym_vars = -1 , int max_iterations = -1 , int stop_at_pc = -1 ) {
590
+ const auto start{std::chrono::steady_clock::now ()};
510
591
wac->interpreter = new ConcolicInterpreter ();
511
592
// Has a big impact on performance, for example if you have a simple program
512
593
// with a loop that contains an if statement and, you run the loop 30 times
@@ -516,6 +597,7 @@ void run_concolic(const std::vector<std::string>& snapshot_messages, int max_ins
516
597
// wac->max_instructions = 900;
517
598
wac->max_instructions = max_instructions;
518
599
wac->max_symbolic_variables = max_sym_vars;
600
+ wac->stop_at_pc = stop_at_pc;
519
601
int total_instructions_executed = 0 ;
520
602
521
603
z3::expr global_condition = m->ctx .bool_val (true );
@@ -638,6 +720,8 @@ void run_concolic(const std::vector<std::string>& snapshot_messages, int max_ins
638
720
z3_pretty_println(m->path_condition);*/
639
721
}
640
722
723
+ const auto finish{std::chrono::steady_clock::now ()};
724
+ const std::chrono::duration<double > elapsed_seconds{finish - start};
641
725
std::cout << std::endl << " === FINISHED ===" << std::endl;
642
726
/* std::cout << "Models found:" << std::endl;
643
727
for (size_t i = 0; i < models.size(); i++) {
@@ -652,7 +736,14 @@ void run_concolic(const std::vector<std::string>& snapshot_messages, int max_ins
652
736
std::cout << " Models found:" << std::endl;
653
737
std::cout << graph.to_string (0 ) << std::endl;
654
738
std::cout << graph.to_json () << std::endl;
655
- std::cout << " Found " << graph.count_leaf_nodes () << " uniqe paths!" << std::endl;
739
+ // std::cout << uint128_to_string(graph.max_states()) << " & " << graph.count_leaf_nodes() << " & " << " & " << graph.max_fanout() << " & " << elapsed_seconds.count() << " \\\\" << std::endl;
740
+ std::cout << graph.max_states () << " & " << graph.count_leaf_nodes () << " & " << graph.max_fanout () << " & " <<
741
+ (max_instructions < 0 ? " $\\ infty$" : std::to_string (max_instructions)) << " & " <<
742
+ (max_sym_vars < 0 ? " $\\ infty$" : std::to_string (max_sym_vars)) << " & " <<
743
+ (max_iterations < 0 ? " $\\ infty$" : std::to_string (max_iterations)) << " & " <<
744
+ std::fixed << std::setprecision (3 ) << elapsed_seconds.count () << " \\\\ " << std::endl;
745
+ // std::cout << uint128_to_string(graph.max_states()) << " & " << graph.count_leaf_nodes() << " & " << graph.min_fanout() << " & " << graph.max_fanout() << " & " << graph.avg_fanout() << " \\\\" << std::endl;
746
+
656
747
/* for (size_t i = 0; i < x0_models.size(); i++) {
657
748
std::cout << "- Model #" << i << ":" << std::endl;
658
749
//z3_pretty_println(x0_models[i].path_condition);
@@ -693,6 +784,7 @@ int main(int argc, const char *argv[]) {
693
784
const char *max_instructions_str = " 50" ;
694
785
const char *max_symbolic_variables_str = " -1" ;
695
786
const char *max_iterations_str = " -1" ;
787
+ const char *stop_at_pc_str = " -1" ;
696
788
bool dump_info = false ;
697
789
698
790
const char *fname = nullptr ;
@@ -786,6 +878,8 @@ int main(int argc, const char *argv[]) {
786
878
ARGV_GET (max_symbolic_variables_str);
787
879
} else if (!strcmp (" --max-iterations" , arg)) {
788
880
ARGV_GET (max_iterations_str);
881
+ } else if (!strcmp (" --stop-at-pc" , arg)) {
882
+ ARGV_GET (stop_at_pc_str);
789
883
} else if (!strcmp (" --dump-info" , arg)) {
790
884
dump_info = true ;
791
885
}
@@ -896,7 +990,7 @@ int main(int argc, const char *argv[]) {
896
990
897
991
// Run Wasm module
898
992
if (strcmp (mode, " concolic" ) == 0 ) {
899
- run_concolic (snapshot_messages, std::stoi (max_instructions_str), std::stoi (max_symbolic_variables_str), std::stoi (max_iterations_str));
993
+ run_concolic (snapshot_messages, std::stoi (max_instructions_str), std::stoi (max_symbolic_variables_str), std::stoi (max_iterations_str), std::stoi (stop_at_pc_str) );
900
994
}
901
995
else {
902
996
// TODO: Add option to calculate the choice points and add them as breakpoints from the remote debugger once
0 commit comments