#!/usr/bin/env perl use strict; use warnings; use diagnostics; use FindBin; use lib $FindBin::Bin; use Util; use Mars; use TUI; use feature 'say'; my $local_wamr = '/home/christoph/Notes/TU/MastersThesis/05 WAMR'; my $local_newlib = '/home/christoph/Notes/TU/MastersThesis/07 NewLib'; my $local_root = '/home/christoph/Notes/TU/MastersThesis/FailNix'; my $local_scripts_dir = "$local_root/scripts"; my $local_builds_dir = "$local_root/builds"; my $local_archive_dir = "$local_root/injections"; my $local_charts_dir = "$local_root/charts"; my $local_ghidra_projects = "$local_root/ghidra/projects"; my $local_ghidra_scripts = "$local_root/ghidra/scripts"; my $local_db_conf = "$local_root/db.conf"; my $remote_root = '/home/lab/smchurla/Documents/failnix'; my $remote_builds_dir = "$remote_root/builds"; my %handlers = ( '01. Build Experiments' => sub { do "$local_scripts_dir/build.pl"; }, '02. Deploy Experiments (Mars)' => sub { do "$local_scripts_dir/deploy.pl"; }, '03. Archive Experiments (Downloads from Mars)' => sub { # Download ran experiments from mars my @dirs = Mars::find_remote_subdirs($remote_builds_dir); my @selected_dirs = TUI::select_from_list( "Select Experiments to Download", 1, @dirs ); die "No experiment selected" unless @selected_dirs; Mars::download_dir( "$remote_builds_dir/$_", "$local_archive_dir/" . $_ =~ s/:/-/gr ) for @selected_dirs; }, '04. Query Databases (Mars)' => sub { # Select databases my @db_names = Mars::db_list(); my @selected_dbs = TUI::select_from_list( "Select Databases to Query", 1, @db_names ); die "No database selected" unless @selected_dbs; # Select queries my @queries = map { s/\.pm//r } Util::find_files("$local_root/scripts/Queries"); my @selected_queries = TUI::select_from_list( "Select Queries to Run", 1, @queries ); die "No query selected" unless @selected_queries; # Run queries on databases foreach my $db (@selected_dbs) { foreach my $query (@selected_queries) { Util::rewrite_file( $local_db_conf, "database=", "database=$db\n" ); say "Running $query on $db..."; Util::execute_query( $db =~ s/smchurla_//r, $query, $local_db_conf, $local_archive_dir, 0 ); } } }, '05. Import Experiments Into Ghidra' => sub { my @existing = Util::find_files($local_ghidra_projects); my $is_old = sub { my ($name) = @_; $name =~ s/:/-/g; return grep { /^$name.gpr$/ } @existing; }; # Import archived experiments into ghidra my @dirs = grep { !$is_old->($_) } Util::find_subdirs($local_archive_dir); my @selected_dirs = TUI::select_from_list( "Select Experiments to Import", 1, @dirs ); foreach (@selected_dirs) { say "Creating Ghidra project for $_..."; system( 'ghidra-analyzeHeadless', $local_ghidra_projects, $_ =~ s/:/-/gr, '-import', "$local_archive_dir/$_/system.elf", '-scriptPath', $local_ghidra_scripts, '-postScript', 'DWARFLineInfoSourceMapScript', '-postScript', 'DWARFLineInfoCommentScript', '-postScript', 'ImportMarkersAsBookmarks', "$local_archive_dir/$_/faults.csv" ); } }, '10. Open Experiment In Explorer' => sub { do "$local_scripts_dir/explore.pl" }, '11. Open Experiment in Ghidra' => sub { my @projects = map { s/\.gpr//r } Util::find_files($local_ghidra_projects); my @selected_projects = TUI::select_from_list( "Select Project to Open in Ghidra", 0, @projects ); die "No project selected" unless @selected_projects; my $project = $selected_projects[0]; system( join " ", ( "_JAVA_AWT_WM_NONREPARENTING=1", "ghidra", "$local_ghidra_projects/$project.gpr", ) ); }, '12. Open Experiment in Binsider' => sub { my @experiments = Util::find_subdirs($local_archive_dir); my @selected_experiments = TUI::select_from_list( "Select Experiments to Plot", 0, @experiments ); die "No experiment selected" unless @selected_experiments; my $selected_experiment = $selected_experiments[0]; system( 'binsider', "$local_archive_dir/$selected_experiment/system.elf" ); }, '13. Open Experiment in ResultBrowser' => sub { # TODO: Select from existing DBs, rewrite db.conf, # launch resultbrowser + firefox }, '14. Run Build in GDB' => sub { my @builds = grep { /linux/ } Util::find_subdirs($local_builds_dir); my @selected_builds = TUI::select_from_list( "Select Build to Run", 0, @builds ); die "No experiment selected" unless @selected_builds; my $selected_build = $selected_builds[0]; my $build_dir = "$local_builds_dir/$selected_build"; my $build_name = $selected_build =~ s/.*-.*-.*:.*:.*?_(.*)-.*-.*/$1/r; my $module_source = "$local_root/build-$build_name"; say "$build_name"; system( 'gdb', '--tui', '-q', "$build_dir/system.elf", '-ex', "set substitute-path '$module_source' '$build_dir'", '-ex', "set substitute-path '/build/source/core' '$local_wamr/core'", '-ex', 'break main', '-ex', 'break fail_start_trace', '-ex', 'break fail_stop_trace', '-ex', 'break fail_marker_positive', '-ex', 'break fail_marker_detected', '-ex', 'break fail_marker_negative', ); }, '20. Plot Results' => sub { # Generate R ggplot2 charts my @experiments = Util::find_subdirs($local_archive_dir); my @selected_experiments = TUI::select_from_list( "Select Experiments to Plot", 1, @experiments ); die "No experiment selected" unless @selected_experiments; my @charts = map { s/\.r//r } Util::find_files($local_charts_dir); my @selected_charts = TUI::select_from_list( "Select Plots to Generate", 1, @charts ); die "No plot selected" unless @selected_charts; my @single_charts = grep { /single/ } @selected_charts; foreach my $experiment (@selected_experiments) { foreach my $chart (@single_charts) { say " - Generating plot $chart for $experiment..."; system( 'Rscript', "$local_charts_dir/$chart.r", "$local_archive_dir/$experiment" ); } } my @combined_charts = grep { /combined/ } @selected_charts; my $print_experiments = join " ", @selected_experiments; my @path_experiments = map { "$local_archive_dir/$_" } @selected_experiments; foreach my $chart (@combined_charts) { say " - Generating plot $chart for ($print_experiments)..."; system( 'Rscript', "$local_charts_dir/$chart.r", @path_experiments ); } }, '95. Delete Builds' => sub { # Delete old build files my @builds = Util::find_subdirs($local_builds_dir); my @selected_builds = TUI::select_from_list( "Select Builds to Delete", 1, @builds ); die "No builds selected" unless @selected_builds; system( 'rm', '-rf', "$local_builds_dir/$_" ) for @selected_builds; }, '96. Delete Builds (Mars)' => sub { # Delete ran experiments from mars my @builds = Mars::find_remote_subdirs($remote_builds_dir); my @selected_builds = TUI::select_from_list( "Select Experiments to Delete", 1, @builds ); die "No experiment selected" unless @selected_builds; Mars::ssh_system( 'rm', '-rf', "$remote_builds_dir/$_" ) for @selected_builds; }, '97. Delete Ghidra Projects' => sub { # Delete ghidra projects my @projects = map { s/\.gpr//r } Util::find_files($local_ghidra_projects); my @selected_projects = TUI::select_from_list( "Select Projects to Delete", 1, @projects ); die "No project selected" unless @selected_projects; system( 'rm', '-rf', "$local_ghidra_projects/$_.gpr" ) for @selected_projects; system( 'rm', '-rf', "$local_ghidra_projects/$_.rep" ) for @selected_projects; }, '98. Delete Archived Experiments' => sub { # Delete archived experiments my @experiments = Util::find_subdirs($local_archive_dir); my @selected_experiments = TUI::select_from_list( "Select Archived Experiments to Delete", 1, @experiments ); die "No experiment selected" unless @selected_experiments; system( 'rm', '-rf', "$local_archive_dir/$_" ) for @selected_experiments; }, '99. Drop Databases (Mars)' => sub { # Drop databases on mars my @db_names = Mars::db_list(); my @selected_dbs = TUI::select_from_list( "Select Databases to Drop", 1, @db_names ); die "No database selected" unless @selected_dbs; Mars::db_drop($_) for @selected_dbs; }, ); while (1) { my @submenu = TUI::select_from_list( "FailNix Menu", 0, sort keys %handlers ); die "No action selected" unless @submenu; say @submenu; eval { $handlers{ $submenu[0] }(); } } Mars::db_disconnect();