(mut config: Config, path: &str)
| 91 | } |
| 92 | |
| 93 | pub fn replay(mut config: Config, path: &str) -> anyhow::Result<()> { |
| 94 | let features = config::EnabledFeatures::from_env()?; |
| 95 | let (mut target, mut vm) = setup_vm(&mut config, &features)?; |
| 96 | target.initialize_vm(&config.fuzzer, &mut vm)?; |
| 97 | |
| 98 | let mut input = MultiStream::from_bytes(&InputSource::from_str(path).read()?) |
| 99 | .with_context(|| format!("Invalid file format: {path}"))?; |
| 100 | modify_input(&mut input); |
| 101 | target.get_mmio_handler(&mut vm).unwrap().clone_from(&input); |
| 102 | |
| 103 | // |
| 104 | // Now we launch in one of three modes depending on what environment variables are configured: |
| 105 | // |
| 106 | |
| 107 | // GDB mode. |
| 108 | if let Ok(addr) = std::env::var("GDB_BIND") { |
| 109 | let elf_path = vm |
| 110 | .env |
| 111 | .as_any() |
| 112 | .downcast_ref::<icicle_cortexm::FuzzwareEnvironment>() |
| 113 | .unwrap() |
| 114 | .elf_path |
| 115 | .clone(); |
| 116 | let mut state = icicle_gdb::ArmStub::new(&mut vm); |
| 117 | if let Some(elf_path) = elf_path { |
| 118 | let is_loopback = |
| 119 | addr.parse::<std::net::SocketAddr>().map_or(false, |x| x.ip().is_loopback()); |
| 120 | // If we are running on a loopback address, assume that GDB will be executed locally |
| 121 | // and we can use the local ELF path (greatly improves performance). |
| 122 | let path = match is_loopback { |
| 123 | false => icicle_gdb::ExePath::Remote(elf_path), |
| 124 | true => icicle_gdb::ExePath::Local(elf_path), |
| 125 | }; |
| 126 | tracing::info!("Setting executable path: {path:?}"); |
| 127 | state.set_exe_path(path); |
| 128 | } |
| 129 | return icicle_gdb::listen(&addr, state, icicle_gdb::CustomCommands::default()); |
| 130 | } |
| 131 | |
| 132 | // Benchmarking mode. |
| 133 | if let Ok(trials_str) = std::env::var("TRIALS") { |
| 134 | let trials = trials_str |
| 135 | .parse::<u64>() |
| 136 | .with_context(|| format!("failed to parse TRIALS={trials_str}"))?; |
| 137 | return replay_bench(vm, target, trials); |
| 138 | } |
| 139 | |
| 140 | // Tracing dumping mode. |
| 141 | replay_trace(vm, target) |
| 142 | } |
| 143 | |
| 144 | fn replay_bench(mut vm: Vm, mut target: CortexmMultiStream, trials: u64) -> anyhow::Result<()> { |
| 145 | let core_ids = core_affinity::get_core_ids().unwrap_or(vec![]); |
no test coverage detected