From 8f4eaf956fcc121fdaa8a1fd536c2da4020a7119 Mon Sep 17 00:00:00 2001 From: Lux Date: Fri, 30 Jan 2026 15:08:46 -0800 Subject: [PATCH 01/24] refactor: use factory for easier config passing --- Cargo.lock | 10 + Cargo.toml | 3 +- configs/linux_631_deepsjeng.json | 26 +++ configs/linux_process_launch.json | 16 +- src/backend/abstract_receiver.rs | 38 ---- src/main.rs | 250 ++++----------------- src/receivers/abstract_receiver.rs | 93 ++++++++ src/receivers/mod.rs | 4 + src/receivers/prv_breakdown_receiver.rs | 97 ++++++++ src/receivers/registry.rs | 44 ++++ src/{backend => receivers}/txt_receiver.rs | 18 +- 11 files changed, 335 insertions(+), 264 deletions(-) create mode 100644 configs/linux_631_deepsjeng.json delete mode 100644 src/backend/abstract_receiver.rs create mode 100644 src/receivers/abstract_receiver.rs create mode 100644 src/receivers/mod.rs create mode 100644 src/receivers/prv_breakdown_receiver.rs create mode 100644 src/receivers/registry.rs rename src/{backend => receivers}/txt_receiver.rs (76%) diff --git a/Cargo.lock b/Cargo.lock index ffbdc98..97997c0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -871,6 +871,15 @@ dependencies = [ "web-time", ] +[[package]] +name = "inventory" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc61209c082fbeb19919bee74b176221b27223e27b65d781eb91af24eb1fb46e" +dependencies = [ + "rustversion", +] + [[package]] name = "ipnet" version = "2.11.0" @@ -1598,6 +1607,7 @@ dependencies = [ "gcno_reader", "indexmap 2.7.1", "indicatif", + "inventory", "jsonschema", "log", "object", diff --git a/Cargo.toml b/Cargo.toml index 79f397a..699d776 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,4 +26,5 @@ addr2line = "0.24.2" indexmap = "2.7.0" jsonschema = "0.17" indicatif = "0.18.0" -rustc_data_structures = "0.1.2" \ No newline at end of file +rustc_data_structures = "0.1.2" +inventory = "0.3" diff --git a/configs/linux_631_deepsjeng.json b/configs/linux_631_deepsjeng.json new file mode 100644 index 0000000..aa09fa0 --- /dev/null +++ b/configs/linux_631_deepsjeng.json @@ -0,0 +1,26 @@ +{ + "encoded_trace": "/scratch/iansseijelly/FIRESIM_RUN_TMP/sim_slot_0/tacit0.out", + "application_binary_asid_tuples": [ + ["../spec2017/speckle/build/overlay/intspeed/test/631.deepsjeng_s/deepsjeng_s_base.riscv-64", "117"] + ], + "sbi_binary": "../firemarshal/images/firechip/spec17-intspeed-test-631-631.deepsjeng_s/spec17-intspeed-test-631-631.deepsjeng_s-bin", + "kernel_binary": "../firemarshal/images/firechip/spec17-intspeed-test-631-631.deepsjeng_s/spec17-intspeed-test-631-631.deepsjeng_s-bin-dwarf", + "kernel_jump_label_patch_log": "/scratch/iansseijelly/tacit-chipyard/sims/firesim/deploy/results-workload/2025-11-15--01-13-55-spec17-intspeed-test-605/spec17-intspeed-test-605-run-chores/jump_label_patch_map.txt", + "driver_binary_entry_tuples": [ + ["../firemarshal/boards/firechip/drivers/tacit-driver/tacit.o", "0xffffffff0169d000"], + ["../firemarshal/boards/firechip/drivers/iceblk-driver/iceblk.o", "0xffffffff016ac000"] + ], + "header_only": false, + "to_stats": false, + "to_txt": false, + "to_stack_txt": false, + "to_atomics": false, + "to_afdo": false, + "gcno": "", + "to_gcda": false, + "to_speedscope": false, + "to_perfetto": false, + "to_foc": false, + "to_vbb": true, + "to_path_profile": false +} diff --git a/configs/linux_process_launch.json b/configs/linux_process_launch.json index 4cda416..242038b 100644 --- a/configs/linux_process_launch.json +++ b/configs/linux_process_launch.json @@ -18,16 +18,8 @@ ["../firemarshal/images/firechip/process-launch/tacit-dwarf", "0xffffffff0169d000"], ["../firemarshal/images/firechip/process-launch/iceblk-dwarf", "0xffffffff016ac000"] ], - "header_only": false, - "to_stats": false, - "to_txt": true, - "to_stack_txt": false, - "to_atomics": false, - "to_afdo": false, - "gcno": "", - "to_gcda": false, - "to_speedscope": true, - "to_perfetto": false, - "to_foc": false, - "to_vbb": false + "receivers": { + "txt": { "enabled": true, "path": "trace.test.txt" }, + "prv_breakdown": { "enabled": true } + } } diff --git a/src/backend/abstract_receiver.rs b/src/backend/abstract_receiver.rs deleted file mode 100644 index ee73b4f..0000000 --- a/src/backend/abstract_receiver.rs +++ /dev/null @@ -1,38 +0,0 @@ -use crate::backend::event::Entry; -use bus::BusReader; -use std::thread; - -pub struct BusReceiver { - pub name: String, // name of the type of receiver - pub bus_rx: BusReader, - pub checksum: usize, -} - -pub trait AbstractReceiver: Send + 'static { - fn bus_rx(&mut self) -> &mut BusReader; - fn try_receive_loop(&mut self) { - loop { - match self.bus_rx().try_recv() { - Ok(entry) => { - self._receive_entry(entry); - self._bump_checksum(); - } - // if the bus is disconnected, we're done! - Err(std::sync::mpsc::TryRecvError::Disconnected) => { - self._flush(); - return; - } - // if the bus is empty, yield until later - Err(std::sync::mpsc::TryRecvError::Empty) => { - thread::yield_now(); - } - } - } - } - // unused - fn _bump_checksum(&mut self); - // step through the trace - fn _receive_entry(&mut self, entry: Entry); - // any final actions - fn _flush(&mut self); -} diff --git a/src/main.rs b/src/main.rs index f9aa195..21e310b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -22,20 +22,11 @@ mod frontend { pub mod trap_type; } +mod receivers; + mod backend { - pub mod abstract_receiver; - pub mod afdo_receiver; - pub mod atomic_receiver; pub mod event; - pub mod gcda_receiver; - pub mod path_profile_receiver; - pub mod perfetto_receiver; - pub mod speedscope_receiver; - pub mod stack_txt_receiver; pub mod stack_unwinder; - pub mod stats_receiver; - pub mod txt_receiver; - pub mod vbb_receiver; } mod common { @@ -59,19 +50,10 @@ use std::io::Write; use bus::Bus; use std::thread; // backend dependency -use backend::abstract_receiver::AbstractReceiver; -use backend::afdo_receiver::AfdoReceiver; -use backend::atomic_receiver::AtomicReceiver; use backend::event::Entry; -use backend::gcda_receiver::GcdaReceiver; -use backend::path_profile_receiver::PathProfileReceiver; -use backend::perfetto_receiver::PerfettoReceiver; -use backend::speedscope_receiver::SpeedscopeReceiver; -use backend::stack_txt_receiver::StackTxtReceiver; -use backend::stats_receiver::StatsReceiver; -use backend::txt_receiver::TxtReceiver; -use backend::vbb_receiver::VBBReceiver; use common::static_cfg::{load_file_config, DecoderStaticCfg}; +use receivers::abstract_receiver::AbstractReceiver; +use receivers::registry; // error handling use anyhow::Result; @@ -87,63 +69,12 @@ struct Args { // optional JSON config file to control receivers #[arg(long)] config: Option, - // path to the encoded trace file - #[arg(short, long)] - encoded_trace: Option, - // path to the binary file - #[arg(long)] - application_binary: Option, - // path to the sbi binary file - #[arg(long)] - sbi_binary: Option, - // path to the kernel binary file - #[arg(long)] - kernel_binary: Option, - // optionally write the final receiver config to JSON - #[arg(long)] - dump_effective_config: Option, // dump the symbol index to a JSON file #[arg(long)] dump_symbol_index: Option, // print the header configuration and exit #[arg(long)] header_only: Option, - // output the decoded trace in stats format - #[arg(long)] - to_stats: Option, - // output the decoded trace in text format - #[arg(long)] - to_txt: Option, - // output the tracked callstack in text format - #[arg(long)] - to_stack_txt: Option, - // output a trace of atomic operations in text format - #[arg(long)] - to_atomics: Option, - // output the decoded trace in afdo format - #[arg(long)] - to_afdo: Option, - // path to the gcno file, must be provided if to_afdo is true - #[arg(long)] - gcno: Option, - // output the decoded trace in gcda format - #[arg(long)] - to_gcda: Option, - // output the decoded trace in speedscope format - #[arg(long)] - to_speedscope: Option, - // output the decoded trace in perfetto format - #[arg(long)] - to_perfetto: Option, - // output the decoded trace in foc format - #[arg(long)] - to_foc: Option, - // output the decoded trace in vbb format - #[arg(long)] - to_vbb: Option, - // output the decoded trace in path profile format - #[arg(long)] - to_path_profile: Option, } fn main() -> Result<()> { @@ -151,56 +82,12 @@ fn main() -> Result<()> { let args = Args::parse(); // If a config file is supplied, use it for receiver toggles (CLI still supplies paths). - let file_cfg = if let Some(path) = &args.config { + let static_cfg = if let Some(path) = &args.config { load_file_config(path)? } else { DecoderStaticCfg::default() }; - fn pick_arg(cli: Option, file: T) -> T { - cli.unwrap_or(file) - } - - // Resolve toggles: config file takes precedence if provided; otherwise use CLI flags - let encoded_trace = pick_arg(args.encoded_trace, file_cfg.encoded_trace); - let application_binary_asid_tuples = file_cfg.application_binary_asid_tuples; - let kernel_binary = pick_arg(args.kernel_binary, file_cfg.kernel_binary); - let kernel_jump_label_patch_log = file_cfg.kernel_jump_label_patch_log; - let driver_binary_entry_tuples = file_cfg.driver_binary_entry_tuples; - let sbi_binary = pick_arg(args.sbi_binary, file_cfg.sbi_binary); - let header_only = pick_arg(args.header_only, file_cfg.header_only); - let to_stats = pick_arg(args.to_stats, file_cfg.to_stats); - let to_txt = pick_arg(args.to_txt, file_cfg.to_txt); - let to_stack_txt = pick_arg(args.to_stack_txt, file_cfg.to_stack_txt); - let to_atomics = pick_arg(args.to_atomics, file_cfg.to_atomics); - let to_afdo = pick_arg(args.to_afdo, file_cfg.to_afdo); - let gcno_path = pick_arg(args.gcno, file_cfg.gcno); - let to_gcda = pick_arg(args.to_gcda, file_cfg.to_gcda); - let to_speedscope = pick_arg(args.to_speedscope, file_cfg.to_speedscope); - let to_perfetto = pick_arg(args.to_perfetto, file_cfg.to_perfetto); - let to_vbb = pick_arg(args.to_vbb, file_cfg.to_vbb); - let to_path_profile = pick_arg(args.to_path_profile, file_cfg.to_path_profile); - let static_cfg = DecoderStaticCfg { - encoded_trace, - application_binary_asid_tuples, - kernel_binary, - kernel_jump_label_patch_log, - driver_binary_entry_tuples, - sbi_binary, - header_only, - to_stats, - to_txt, - to_stack_txt, - to_atomics, - to_afdo, - gcno: gcno_path.clone(), - to_gcda, - to_speedscope, - to_perfetto, - to_vbb, - to_path_profile, - }; - // verify the binary exists and is a file for (binary, _) in static_cfg.application_binary_asid_tuples.clone() { if !Path::new(&binary).exists() || !Path::new(&binary).is_file() { @@ -239,11 +126,6 @@ fn main() -> Result<()> { )); } - if let Some(path) = &args.dump_effective_config { - let mut f = std::fs::File::create(path)?; - serde_json::to_writer_pretty(&mut f, &static_cfg)?; - } - let (first_packet, runtime_cfg) = { let trace_file = File::open(static_cfg.encoded_trace.clone())?; let mut trace_reader = BufReader::new(trace_file); @@ -290,94 +172,42 @@ fn main() -> Result<()> { let mut bus: Bus = Bus::new(BUS_SIZE); let mut receivers: Vec> = vec![]; - // add a receiver to the bus for stats output - if to_stats { - let encoded_trace_file = File::open(static_cfg.encoded_trace.clone())?; - // get the file size - let file_size = encoded_trace_file.metadata()?.len(); - // close the file - drop(encoded_trace_file); - let stats_bus_endpoint = bus.add_rx(); - receivers.push(Box::new(StatsReceiver::new( - stats_bus_endpoint, - runtime_cfg.clone(), - file_size, - ))); - } - - // add a receiver to the bus for txt output - if to_txt { - let txt_bus_endpoint = bus.add_rx(); - receivers.push(Box::new(TxtReceiver::new(txt_bus_endpoint))); - } - - if to_stack_txt { - let to_stack_txt_symbol_index = std::sync::Arc::clone(&symbol_index); - let stack_txt_rx = StackTxtReceiver::new( - bus.add_rx(), - to_stack_txt_symbol_index, - ); - receivers.push(Box::new(stack_txt_rx)); - } - - if to_atomics { - let to_atomics_symbol_index = std::sync::Arc::clone(&symbol_index); - let atomic_rx = - AtomicReceiver::new(bus.add_rx(), to_atomics_symbol_index); - receivers.push(Box::new(atomic_rx)); - } - - if to_afdo { - let afdo_bus_endpoint = bus.add_rx(); - let mut elf_file = File::open(static_cfg.application_binary_asid_tuples[0].0.clone())?; - let mut elf_buffer = Vec::new(); - elf_file.read_to_end(&mut elf_buffer)?; - let elf = object::File::parse(&*elf_buffer)?; - receivers.push(Box::new(AfdoReceiver::new( - afdo_bus_endpoint, - elf.entry().clone(), - ))); - drop(elf_file); - } - - if to_gcda { - let gcda_bus_endpoint = bus.add_rx(); - receivers.push(Box::new(GcdaReceiver::new( - gcda_bus_endpoint, - gcno_path.clone(), - static_cfg.application_binary_asid_tuples[0].0.clone(), - ))); - } - - if to_speedscope { - let speedscope_bus_endpoint = bus.add_rx(); - let speedscope_symbol_index = std::sync::Arc::clone(&symbol_index); - receivers.push(Box::new(SpeedscopeReceiver::new( - speedscope_bus_endpoint, - speedscope_symbol_index, - ))); - } - - if to_perfetto { - let perfetto_bus_endpoint = bus.add_rx(); - let perfetto_symbol_index = std::sync::Arc::clone(&symbol_index); - receivers.push(Box::new(PerfettoReceiver::new( - perfetto_bus_endpoint, - perfetto_symbol_index, - ))); - } + let receiver_cfg = if let Some(path) = &args.config { + let f = File::open(path)?; + let reader = BufReader::new(f); + let value: serde_json::Value = serde_json::from_reader(reader)?; + value + .get("receivers") + .cloned() + .unwrap_or_else(|| serde_json::Value::Null) + } else { + serde_json::Value::Null + }; - if to_vbb { - let vbb_bus_endpoint = bus.add_rx(); - receivers.push(Box::new(VBBReceiver::new(vbb_bus_endpoint))); - } - if to_path_profile { - let path_profile_bus_endpoint = bus.add_rx(); - let path_profile_symbol_index = std::sync::Arc::clone(&symbol_index); - receivers.push(Box::new(PathProfileReceiver::new( - path_profile_bus_endpoint, - path_profile_symbol_index, - ))); + if !receiver_cfg.is_null() { + let shared = receivers::abstract_receiver::Shared { + static_cfg: static_cfg.clone(), + runtime_cfg: runtime_cfg.clone(), + symbol_index: None, + insn_index: None, + }; + + let receiver_map = receiver_cfg.as_object().ok_or_else(|| { + anyhow::anyhow!("receivers config must be an object map of name -> config") + })?; + for (name, cfg) in receiver_map { + let enabled = cfg + .get("enabled") + .and_then(|value| value.as_bool()) + .unwrap_or(true); + if !enabled { + continue; + } + let bus_rx = bus.add_rx(); + let receiver = + registry::make_receiver(name, &shared, cfg.clone(), bus_rx)?; + receivers.push(receiver); + } } let encoded_trace_path = static_cfg.encoded_trace.clone(); diff --git a/src/receivers/abstract_receiver.rs b/src/receivers/abstract_receiver.rs new file mode 100644 index 0000000..329a62e --- /dev/null +++ b/src/receivers/abstract_receiver.rs @@ -0,0 +1,93 @@ +use crate::backend::event::Entry; +use crate::common::insn_index::{build_instruction_index, InstructionIndex}; +use crate::common::static_cfg::DecoderStaticCfg; +use crate::common::symbol_index::{build_symbol_index, SymbolIndex}; +use crate::frontend::runtime_cfg::DecoderRuntimeCfg; +use anyhow::Result; +use bus::BusReader; +use std::sync::Arc; +use std::thread; + +pub struct BusReceiver { + pub name: String, // name of the type of receiver + pub bus_rx: BusReader, + pub checksum: usize, +} + +pub trait AbstractReceiver: Send + 'static { + fn bus_rx(&mut self) -> &mut BusReader; + fn try_receive_loop(&mut self) { + loop { + match self.bus_rx().try_recv() { + Ok(entry) => { + self._receive_entry(entry); + self._bump_checksum(); + } + // if the bus is disconnected, we're done! + Err(std::sync::mpsc::TryRecvError::Disconnected) => { + self._flush(); + return; + } + // if the bus is empty, yield until later + Err(std::sync::mpsc::TryRecvError::Empty) => { + thread::yield_now(); + } + } + } + } + // unused + fn _bump_checksum(&mut self); + // step through the trace + fn _receive_entry(&mut self, entry: Entry); + // any final actions + fn _flush(&mut self); +} + +pub struct Shared { + pub static_cfg: DecoderStaticCfg, + pub runtime_cfg: DecoderRuntimeCfg, + pub symbol_index: Option>, + pub insn_index: Option>, +} + +pub struct SharedBuilder { + static_cfg: DecoderStaticCfg, + runtime_cfg: DecoderRuntimeCfg, + symbol_index: Option>, + insn_index: Option> +} + +impl SharedBuilder { + pub fn new(static_cfg: DecoderStaticCfg, runtime_cfg: DecoderRuntimeCfg) -> Self { + Self { + static_cfg, + runtime_cfg, + symbol_index: None, + insn_index: None, + } + } + + pub fn with_symbol_index(mut self) -> Result { + if self.symbol_index.is_none() { + self.symbol_index = Some(Arc::new(build_symbol_index(self.static_cfg.clone())?)); + } + Ok(self) + } + + pub fn with_insn_index(mut self) -> Result { + if self.insn_index.is_none() { + self.insn_index = + Some(Arc::new(build_instruction_index(self.static_cfg.clone())?)); + } + Ok(self) + } + + pub fn build(self) -> Shared { + Shared { + static_cfg: self.static_cfg, + runtime_cfg: self.runtime_cfg, + symbol_index: self.symbol_index, + insn_index: self.insn_index, + } + } +} diff --git a/src/receivers/mod.rs b/src/receivers/mod.rs new file mode 100644 index 0000000..33278ba --- /dev/null +++ b/src/receivers/mod.rs @@ -0,0 +1,4 @@ +pub mod abstract_receiver; +pub mod registry; +pub mod txt_receiver; +pub mod prv_breakdown_receiver; \ No newline at end of file diff --git a/src/receivers/prv_breakdown_receiver.rs b/src/receivers/prv_breakdown_receiver.rs new file mode 100644 index 0000000..9e07808 --- /dev/null +++ b/src/receivers/prv_breakdown_receiver.rs @@ -0,0 +1,97 @@ +use crate::receivers::abstract_receiver::{AbstractReceiver, BusReceiver, Shared}; +use crate::backend::event::{Entry, EventKind}; +use bus::BusReader; +use crate::common::prv::Prv; + +/* Receiver for answering the question: "How many cycles were executed in each privilege level?" */ +pub struct PrvBreakdownReceiver { + receiver: BusReceiver, + curr_prv: Prv, + u_prv_cycles: u64, + k_prv_cycles: u64, + m_prv_cycles: u64, + prev_timestamp: u64, +} + +impl PrvBreakdownReceiver { + pub fn new(bus_rx: BusReader) -> Self { + Self { + receiver: BusReceiver { + name: "prv_breakdown".to_string(), + bus_rx: bus_rx, + checksum: 0, + }, + curr_prv: Prv::PrvUser, + u_prv_cycles: 0, + k_prv_cycles: 0, + m_prv_cycles: 0, + prev_timestamp: 0, + } + } +} + +pub fn factory( + _shared: &Shared, + _config: serde_json::Value, + bus_rx: BusReader, +) -> Box { + Box::new(PrvBreakdownReceiver::new(bus_rx)) +} + +crate::register_receiver!("prv_breakdown", factory); + +impl AbstractReceiver for PrvBreakdownReceiver { + fn bus_rx(&mut self) -> &mut BusReader { + &mut self.receiver.bus_rx + } + + fn _bump_checksum(&mut self) { + self.receiver.checksum += 1; + } + + fn _receive_entry(&mut self, entry: Entry) { + match entry { + Entry::Event { timestamp, kind: EventKind::SyncStart { start_prv, .. } } => { + self.curr_prv = start_prv; + self.prev_timestamp = timestamp; + } + Entry::Event { timestamp, kind: EventKind::Trap { prv_arc, .. } } => { + self.update_prv_cycles(timestamp); + self.curr_prv = prv_arc.1; + } + Entry::Event { timestamp, .. } => { + self.update_prv_cycles(timestamp); + } + Entry::Instruction { .. } => { + // do nothing + } + } + } + + fn _flush(&mut self) { + let total_cycles = self.u_prv_cycles + self.k_prv_cycles + self.m_prv_cycles; + println!("User privilege level cycles: {} ({:.2}%)", self.u_prv_cycles, self.u_prv_cycles as f64 / total_cycles as f64 * 100.0); + println!("Supervisor privilege level cycles: {} ({:.2}%)", self.k_prv_cycles, self.k_prv_cycles as f64 / total_cycles as f64 * 100.0); + println!("Machine privilege level cycles: {} ({:.2}%)", self.m_prv_cycles, self.m_prv_cycles as f64 / total_cycles as f64 * 100.0); + } +} + +impl PrvBreakdownReceiver { + fn update_prv_cycles(&mut self, timestamp: u64) { + match self.curr_prv { + Prv::PrvUser => { + self.u_prv_cycles += timestamp - self.prev_timestamp; + } + Prv::PrvSupervisor => { + self.k_prv_cycles += timestamp - self.prev_timestamp; + } + Prv::PrvMachine => { + self.m_prv_cycles += timestamp - self.prev_timestamp; + } + _ => { + panic!("Unsupported privilege level: {:?}", self.curr_prv); + } + } + self.prev_timestamp = timestamp; + } +} diff --git a/src/receivers/registry.rs b/src/receivers/registry.rs new file mode 100644 index 0000000..140658b --- /dev/null +++ b/src/receivers/registry.rs @@ -0,0 +1,44 @@ +use crate::backend::event::Entry; +use crate::receivers::abstract_receiver::{AbstractReceiver, Shared}; +use anyhow::Result; +use bus::BusReader; + +pub type ReceiverFactory = + fn(shared: &Shared, config: serde_json::Value, bus_rx: BusReader) + -> Box; + +pub struct ReceiverRegistration { + pub name: &'static str, + pub factory: ReceiverFactory, +} + +::inventory::collect!(ReceiverRegistration); + +#[macro_export] +macro_rules! register_receiver { + ($name:expr, $factory:path) => { + ::inventory::submit! { + $crate::receivers::registry::ReceiverRegistration { + name: $name, + factory: $factory, + } + } + }; +} + +pub fn make_receiver( + name: &str, + shared: &Shared, + config: serde_json::Value, + bus_rx: BusReader, +) -> Result> { + for reg in ::inventory::iter:: { + if reg.name == name { + return Ok((reg.factory)(shared, config, bus_rx)); + } + } + Err(anyhow::anyhow!( + "Receiver factory not found for name: {}", + name + )) +} diff --git a/src/backend/txt_receiver.rs b/src/receivers/txt_receiver.rs similarity index 76% rename from src/backend/txt_receiver.rs rename to src/receivers/txt_receiver.rs index 0d34723..c265517 100644 --- a/src/backend/txt_receiver.rs +++ b/src/receivers/txt_receiver.rs @@ -1,4 +1,4 @@ -use crate::backend::abstract_receiver::{AbstractReceiver, BusReceiver}; +use crate::receivers::abstract_receiver::{AbstractReceiver, BusReceiver, Shared}; use crate::backend::event::{Entry, EventKind}; use bus::BusReader; use std::fs::File; @@ -9,10 +9,11 @@ pub struct TxtReceiver { receiver: BusReceiver, } +/* Receiver for dumping the trace to a text file */ impl TxtReceiver { - pub fn new(bus_rx: BusReader) -> Self { + pub fn new(bus_rx: BusReader, path: String) -> Self { Self { - writer: BufWriter::new(File::create("trace.txt").unwrap()), + writer: BufWriter::new(File::create(path).unwrap()), receiver: BusReceiver { name: "txt".to_string(), bus_rx: bus_rx, @@ -22,6 +23,17 @@ impl TxtReceiver { } } +pub fn factory( + _shared: &Shared, + _config: serde_json::Value, + bus_rx: BusReader, +) -> Box { + let path = _config.get("path").and_then(|value| value.as_str()).unwrap_or("trace.txt").to_string(); + Box::new(TxtReceiver::new(bus_rx, path)) +} + +crate::register_receiver!("txt", factory); + impl AbstractReceiver for TxtReceiver { fn bus_rx(&mut self) -> &mut BusReader { &mut self.receiver.bus_rx From 96740776bfa2f819159bf88ddb2889f733db452d Mon Sep 17 00:00:00 2001 From: Lux Date: Fri, 30 Jan 2026 15:27:04 -0800 Subject: [PATCH 02/24] refactor: update configuration for receivers and remove unused components, add back speedscope receiver --- configs/linux_process_launch.json | 5 +- src/main.rs | 8 +-- src/receivers/abstract_receiver.rs | 53 ++++--------------- src/receivers/mod.rs | 5 +- src/receivers/prv_breakdown_receiver.rs | 3 ++ .../speedscope_receiver.rs | 20 +++++-- src/{backend => receivers}/stack_unwinder.rs | 0 7 files changed, 39 insertions(+), 55 deletions(-) rename src/{backend => receivers}/speedscope_receiver.rs (92%) rename src/{backend => receivers}/stack_unwinder.rs (100%) diff --git a/configs/linux_process_launch.json b/configs/linux_process_launch.json index 242038b..564d962 100644 --- a/configs/linux_process_launch.json +++ b/configs/linux_process_launch.json @@ -19,7 +19,8 @@ ["../firemarshal/images/firechip/process-launch/iceblk-dwarf", "0xffffffff016ac000"] ], "receivers": { - "txt": { "enabled": true, "path": "trace.test.txt" }, - "prv_breakdown": { "enabled": true } + "txt": { "enabled": false, "path": "trace.test.txt" }, + "prv_breakdown": { "enabled": true }, + "speedscope": { "enabled": true, "path": "trace.speedscope.json" } } } diff --git a/src/main.rs b/src/main.rs index 21e310b..c0af1a1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -26,7 +26,6 @@ mod receivers; mod backend { pub mod event; - pub mod stack_unwinder; } mod common { @@ -185,12 +184,7 @@ fn main() -> Result<()> { }; if !receiver_cfg.is_null() { - let shared = receivers::abstract_receiver::Shared { - static_cfg: static_cfg.clone(), - runtime_cfg: runtime_cfg.clone(), - symbol_index: None, - insn_index: None, - }; + let shared = receivers::abstract_receiver::Shared::new(&static_cfg, &runtime_cfg)?; let receiver_map = receiver_cfg.as_object().ok_or_else(|| { anyhow::anyhow!("receivers config must be an object map of name -> config") diff --git a/src/receivers/abstract_receiver.rs b/src/receivers/abstract_receiver.rs index 329a62e..6e07591 100644 --- a/src/receivers/abstract_receiver.rs +++ b/src/receivers/abstract_receiver.rs @@ -46,48 +46,17 @@ pub trait AbstractReceiver: Send + 'static { pub struct Shared { pub static_cfg: DecoderStaticCfg, pub runtime_cfg: DecoderRuntimeCfg, - pub symbol_index: Option>, - pub insn_index: Option>, + pub symbol_index: Arc, + pub insn_index: Arc, } -pub struct SharedBuilder { - static_cfg: DecoderStaticCfg, - runtime_cfg: DecoderRuntimeCfg, - symbol_index: Option>, - insn_index: Option> -} - -impl SharedBuilder { - pub fn new(static_cfg: DecoderStaticCfg, runtime_cfg: DecoderRuntimeCfg) -> Self { - Self { - static_cfg, - runtime_cfg, - symbol_index: None, - insn_index: None, - } +impl Shared { + pub fn new(static_cfg: &DecoderStaticCfg, runtime_cfg: &DecoderRuntimeCfg) -> Result { + Ok(Self { + static_cfg: static_cfg.clone(), + runtime_cfg: runtime_cfg.clone(), + symbol_index: Arc::new(build_symbol_index(static_cfg.clone())?), + insn_index: Arc::new(build_instruction_index(static_cfg.clone())?), + }) } - - pub fn with_symbol_index(mut self) -> Result { - if self.symbol_index.is_none() { - self.symbol_index = Some(Arc::new(build_symbol_index(self.static_cfg.clone())?)); - } - Ok(self) - } - - pub fn with_insn_index(mut self) -> Result { - if self.insn_index.is_none() { - self.insn_index = - Some(Arc::new(build_instruction_index(self.static_cfg.clone())?)); - } - Ok(self) - } - - pub fn build(self) -> Shared { - Shared { - static_cfg: self.static_cfg, - runtime_cfg: self.runtime_cfg, - symbol_index: self.symbol_index, - insn_index: self.insn_index, - } - } -} +} \ No newline at end of file diff --git a/src/receivers/mod.rs b/src/receivers/mod.rs index 33278ba..5414b71 100644 --- a/src/receivers/mod.rs +++ b/src/receivers/mod.rs @@ -1,4 +1,7 @@ pub mod abstract_receiver; pub mod registry; +pub mod stack_unwinder; + pub mod txt_receiver; -pub mod prv_breakdown_receiver; \ No newline at end of file +pub mod prv_breakdown_receiver; +pub mod speedscope_receiver; \ No newline at end of file diff --git a/src/receivers/prv_breakdown_receiver.rs b/src/receivers/prv_breakdown_receiver.rs index 9e07808..d00e0d5 100644 --- a/src/receivers/prv_breakdown_receiver.rs +++ b/src/receivers/prv_breakdown_receiver.rs @@ -69,10 +69,13 @@ impl AbstractReceiver for PrvBreakdownReceiver { } fn _flush(&mut self) { + println!("--------------------------------"); + println!("Privilege level breakdown:"); let total_cycles = self.u_prv_cycles + self.k_prv_cycles + self.m_prv_cycles; println!("User privilege level cycles: {} ({:.2}%)", self.u_prv_cycles, self.u_prv_cycles as f64 / total_cycles as f64 * 100.0); println!("Supervisor privilege level cycles: {} ({:.2}%)", self.k_prv_cycles, self.k_prv_cycles as f64 / total_cycles as f64 * 100.0); println!("Machine privilege level cycles: {} ({:.2}%)", self.m_prv_cycles, self.m_prv_cycles as f64 / total_cycles as f64 * 100.0); + println!("--------------------------------"); } } diff --git a/src/backend/speedscope_receiver.rs b/src/receivers/speedscope_receiver.rs similarity index 92% rename from src/backend/speedscope_receiver.rs rename to src/receivers/speedscope_receiver.rs index 99ca7cb..ee6d614 100644 --- a/src/backend/speedscope_receiver.rs +++ b/src/receivers/speedscope_receiver.rs @@ -1,6 +1,6 @@ -use crate::backend::abstract_receiver::{AbstractReceiver, BusReceiver}; +use crate::receivers::abstract_receiver::{AbstractReceiver, BusReceiver, Shared}; use crate::backend::event::{Entry, EventKind}; -use crate::backend::stack_unwinder::{Frame, StackUnwinder, StackUpdateResult}; +use crate::receivers::stack_unwinder::{Frame, StackUnwinder, StackUpdateResult}; use crate::common::prv::Prv; use crate::common::symbol_index::SymbolIndex; use bus::BusReader; @@ -56,6 +56,7 @@ impl SpeedscopeReceiver { pub fn new( bus_rx: BusReader, symbols: Arc, + path: String, ) -> Self { debug!("SpeedscopeReceiver::new"); @@ -65,7 +66,7 @@ impl SpeedscopeReceiver { let (frames, frame_lookup) = build_frames(&symbols); Self { - writer: BufWriter::new(File::create("trace.speedscope.json").unwrap()), + writer: BufWriter::new(File::create(path).unwrap()), receiver: BusReceiver { name: "speedscope".into(), bus_rx, @@ -79,7 +80,20 @@ impl SpeedscopeReceiver { unwinder, } } +} + +pub fn factory( + _shared: &Shared, + _config: serde_json::Value, + bus_rx: BusReader, +) -> Box { + let path = _config.get("path").and_then(|value| value.as_str()).unwrap_or("trace.speedscope.json").to_string(); + Box::new(SpeedscopeReceiver::new(bus_rx, _shared.symbol_index.clone(), path)) +} +crate::register_receiver!("speedscope", factory); + +impl SpeedscopeReceiver { fn record_stack_update(&mut self, ts: u64, update: StackUpdateResult) { for frame in update.frames_closed { if let Some(id) = self.lookup_frame(&frame) { diff --git a/src/backend/stack_unwinder.rs b/src/receivers/stack_unwinder.rs similarity index 100% rename from src/backend/stack_unwinder.rs rename to src/receivers/stack_unwinder.rs From 0446a71415097d3d95e8ebb185e2715a76f2e625 Mon Sep 17 00:00:00 2001 From: Lux Date: Fri, 30 Jan 2026 15:34:44 -0800 Subject: [PATCH 03/24] mov: more receivers like stack and bb(vbb) --- .../bb_stats_receiver.rs} | 28 ++++++++++++++----- src/receivers/mod.rs | 4 ++- .../stack_txt_receiver.rs | 22 +++++++++++---- 3 files changed, 41 insertions(+), 13 deletions(-) rename src/{backend/vbb_receiver.rs => receivers/bb_stats_receiver.rs} (82%) rename src/{backend => receivers}/stack_txt_receiver.rs (80%) diff --git a/src/backend/vbb_receiver.rs b/src/receivers/bb_stats_receiver.rs similarity index 82% rename from src/backend/vbb_receiver.rs rename to src/receivers/bb_stats_receiver.rs index 4ae48c1..31c5246 100644 --- a/src/backend/vbb_receiver.rs +++ b/src/receivers/bb_stats_receiver.rs @@ -1,4 +1,4 @@ -use crate::backend::abstract_receiver::{AbstractReceiver, BusReceiver}; +use crate::receivers::abstract_receiver::{AbstractReceiver, BusReceiver, Shared}; use crate::backend::event::{Entry, EventKind}; use bus::BusReader; @@ -12,7 +12,8 @@ pub struct BB { end_addr: u64, } -pub struct VBBReceiver { +/* Receiver for answering the question: "How many cycles were executed in each basic block?" */ +pub struct BBStatsReceiver { writer: BufWriter, receiver: BusReceiver, bb_records: HashMap>, @@ -20,12 +21,12 @@ pub struct VBBReceiver { prev_timestamp: u64, } -impl VBBReceiver { - pub fn new(bus_rx: BusReader) -> Self { +impl BBStatsReceiver { + pub fn new(bus_rx: BusReader, path: String) -> Self { Self { - writer: BufWriter::new(File::create("trace.vbb.csv").unwrap()), + writer: BufWriter::new(File::create(path).unwrap()), receiver: BusReceiver { - name: "vbb".to_string(), + name: "bb_stats".to_string(), bus_rx, checksum: 0, }, @@ -34,7 +35,20 @@ impl VBBReceiver { prev_timestamp: 0, } } +} + +pub fn factory( + _shared: &Shared, + _config: serde_json::Value, + bus_rx: BusReader, +) -> Box { + let path = _config.get("path").and_then(|value| value.as_str()).unwrap_or("trace.bb_stats.csv").to_string(); + Box::new(BBStatsReceiver::new(bus_rx, path)) +} + +crate::register_receiver!("bb_stats", factory); +impl BBStatsReceiver { fn update_bb_records(&mut self, from_addr: u64, to_addr: u64, timestamp: u64) { let bb = BB { start_addr: self.prev_addr, @@ -54,7 +68,7 @@ impl VBBReceiver { } } -impl AbstractReceiver for VBBReceiver { +impl AbstractReceiver for BBStatsReceiver { fn bus_rx(&mut self) -> &mut BusReader { &mut self.receiver.bus_rx } diff --git a/src/receivers/mod.rs b/src/receivers/mod.rs index 5414b71..33e6ae0 100644 --- a/src/receivers/mod.rs +++ b/src/receivers/mod.rs @@ -4,4 +4,6 @@ pub mod stack_unwinder; pub mod txt_receiver; pub mod prv_breakdown_receiver; -pub mod speedscope_receiver; \ No newline at end of file +pub mod speedscope_receiver; +pub mod stack_txt_receiver; +pub mod bb_stats_receiver; \ No newline at end of file diff --git a/src/backend/stack_txt_receiver.rs b/src/receivers/stack_txt_receiver.rs similarity index 80% rename from src/backend/stack_txt_receiver.rs rename to src/receivers/stack_txt_receiver.rs index e347a82..456b997 100644 --- a/src/backend/stack_txt_receiver.rs +++ b/src/receivers/stack_txt_receiver.rs @@ -1,13 +1,12 @@ -use crate::backend::abstract_receiver::{AbstractReceiver, BusReceiver}; +use crate::receivers::abstract_receiver::{AbstractReceiver, BusReceiver, Shared}; use crate::backend::event::Entry; -use crate::backend::stack_unwinder::{StackUnwinder, StackUpdateResult}; +use crate::receivers::stack_unwinder::{StackUnwinder, StackUpdateResult}; +use crate::common::symbol_index::SymbolIndex; use bus::BusReader; use std::fs::File; use std::io::{BufWriter, Write}; use std::sync::Arc; -use crate::common::symbol_index::SymbolIndex; - pub struct StackTxtReceiver { writer: BufWriter, receiver: BusReceiver, @@ -18,10 +17,11 @@ impl StackTxtReceiver { pub fn new( bus_rx: BusReader, symbols: Arc, + path: String, ) -> Self { let unwinder = StackUnwinder::new(symbols).expect("init unwinder"); Self { - writer: BufWriter::new(File::create("trace.stack.txt").unwrap()), + writer: BufWriter::new(File::create(path).unwrap()), receiver: BusReceiver { name: "stacktxt".into(), bus_rx, @@ -30,7 +30,19 @@ impl StackTxtReceiver { unwinder, } } +} +pub fn factory( + _shared: &Shared, + _config: serde_json::Value, + bus_rx: BusReader, +) -> Box { + let path = _config.get("path").and_then(|value| value.as_str()).unwrap_or("trace.stack.txt").to_string(); + Box::new(StackTxtReceiver::new(bus_rx, Arc::clone(&_shared.symbol_index), path)) +} +crate::register_receiver!("stack_txt", factory); + +impl StackTxtReceiver { fn dump_current_stack(&mut self) -> std::io::Result<()> { let all_frames = self.unwinder.peek_all_frames(); let size = all_frames.len(); From 78c2ad0afa7014d16e4a616d3203bfcdff696872 Mon Sep 17 00:00:00 2001 From: Lux Date: Fri, 30 Jan 2026 16:04:23 -0800 Subject: [PATCH 04/24] add: move path profile to new API --- src/receivers/mod.rs | 3 ++- .../path_profile_receiver.rs | 20 +++++++++++++++---- 2 files changed, 18 insertions(+), 5 deletions(-) rename src/{backend => receivers}/path_profile_receiver.rs (89%) diff --git a/src/receivers/mod.rs b/src/receivers/mod.rs index 33e6ae0..cc58029 100644 --- a/src/receivers/mod.rs +++ b/src/receivers/mod.rs @@ -6,4 +6,5 @@ pub mod txt_receiver; pub mod prv_breakdown_receiver; pub mod speedscope_receiver; pub mod stack_txt_receiver; -pub mod bb_stats_receiver; \ No newline at end of file +pub mod bb_stats_receiver; +pub mod path_profile_receiver; \ No newline at end of file diff --git a/src/backend/path_profile_receiver.rs b/src/receivers/path_profile_receiver.rs similarity index 89% rename from src/backend/path_profile_receiver.rs rename to src/receivers/path_profile_receiver.rs index de68689..81b3e02 100644 --- a/src/backend/path_profile_receiver.rs +++ b/src/receivers/path_profile_receiver.rs @@ -1,13 +1,12 @@ -use crate::backend::abstract_receiver::{AbstractReceiver, BusReceiver}; +use crate::receivers::abstract_receiver::{AbstractReceiver, BusReceiver, Shared}; use crate::backend::event::{Entry, EventKind}; -use crate::backend::stack_unwinder::StackUnwinder; +use crate::receivers::stack_unwinder::StackUnwinder; use crate::common::symbol_index::SymbolIndex; use bus::BusReader; use std::collections::HashMap; use std::fs::File; use std::io::{BufWriter, Write}; use std::sync::Arc; -use std::collections::BTreeMap; #[derive(Hash, PartialEq, Eq, Clone)] pub struct Path { @@ -60,11 +59,12 @@ impl PathProfileReceiver { pub fn new( bus_rx: BusReader, symbols: Arc, + path: String, ) -> Self { let unwinder = StackUnwinder::new(Arc::clone(&symbols)).expect("stack unwinder"); Self { - writer: BufWriter::new(File::create("trace.path_profile.csv").unwrap()), + writer: BufWriter::new(File::create(path).unwrap()), receiver: BusReceiver { name: "path_profile".to_string(), bus_rx, @@ -76,7 +76,19 @@ impl PathProfileReceiver { current_start_time: 0, } } +} + +pub fn factory( + _shared: &Shared, + _config: serde_json::Value, + bus_rx: BusReader, +) -> Box { + let path = _config.get("path").and_then(|value| value.as_str()).unwrap_or("trace.path_profile.csv").to_string(); + Box::new(PathProfileReceiver::new(bus_rx, _shared.symbol_index.clone(), path)) +} +crate::register_receiver!("path_profile", factory); +impl PathProfileReceiver { fn record_branch(&mut self, taken: bool) { // peek the top of the current paths if let Some(ref mut path) = self.current_path { From 9390835319a4b19154a3840b200fd0805f2b93bc Mon Sep 17 00:00:00 2001 From: Lux Date: Fri, 30 Jan 2026 16:29:58 -0800 Subject: [PATCH 05/24] refactor: move things around, done refactoring --- .../baremetal_firesim.json | 15 +- .../baremetal_hello_boom.json | 15 +- .../baremetal_hello_spike.json | 15 +- .../baremetal_rocket.json} | 15 +- configs/{ => embench}/baremetal_crc32.json | 13 +- configs/{ => embench}/baremetal_edn.json | 0 .../{ => embench}/baremetal_huffbench.json | 13 +- .../{ => embench}/baremetal_nettlesha256.json | 13 +- configs/{ => embench}/baremetal_wikisort.json | 13 +- configs/jump_label_patch_map.txt | 4077 ----------------- configs/{ => linux}/linux.json | 0 configs/{ => linux}/linux_firesim.json | 0 configs/{ => linux}/linux_process_launch.json | 3 +- configs/linux_spec.json | 28 - configs/{ => robotics}/baremetal_foc.json | 15 +- .../{ => robotics}/baremetal_freertos.json | 15 +- configs/{ => spec}/linux_600_perlbench.json | 0 configs/{ => spec}/linux_605_mcf.json | 0 configs/{ => spec}/linux_625_x264.json | 0 configs/{ => spec}/linux_631_deepsjeng.json | 0 configs/{ => spec}/linux_641_leela.json | 0 configs/{ => spec}/linux_648_exchange2.json | 0 src/backend/stats_receiver.rs | 109 - src/{backend => receivers}/afdo_receiver.rs | 15 +- src/{backend => receivers}/atomic_receiver.rs | 14 +- src/receivers/bb_stats_receiver.rs | 39 +- src/{backend => receivers}/gcda_receiver.rs | 15 +- src/receivers/mod.rs | 8 +- .../perfetto_receiver.rs | 14 +- 29 files changed, 121 insertions(+), 4343 deletions(-) rename configs/{ => baremetal_hello}/baremetal_firesim.json (54%) rename configs/{ => baremetal_hello}/baremetal_hello_boom.json (53%) rename configs/{ => baremetal_hello}/baremetal_hello_spike.json (52%) rename configs/{baremetal.json => baremetal_hello/baremetal_rocket.json} (53%) rename configs/{ => embench}/baremetal_crc32.json (53%) rename configs/{ => embench}/baremetal_edn.json (100%) rename configs/{ => embench}/baremetal_huffbench.json (53%) rename configs/{ => embench}/baremetal_nettlesha256.json (54%) rename configs/{ => embench}/baremetal_wikisort.json (53%) delete mode 100644 configs/jump_label_patch_map.txt rename configs/{ => linux}/linux.json (100%) rename configs/{ => linux}/linux_firesim.json (100%) rename configs/{ => linux}/linux_process_launch.json (93%) delete mode 100644 configs/linux_spec.json rename configs/{ => robotics}/baremetal_foc.json (52%) rename configs/{ => robotics}/baremetal_freertos.json (56%) rename configs/{ => spec}/linux_600_perlbench.json (100%) rename configs/{ => spec}/linux_605_mcf.json (100%) rename configs/{ => spec}/linux_625_x264.json (100%) rename configs/{ => spec}/linux_631_deepsjeng.json (100%) rename configs/{ => spec}/linux_641_leela.json (100%) rename configs/{ => spec}/linux_648_exchange2.json (100%) delete mode 100644 src/backend/stats_receiver.rs rename src/{backend => receivers}/afdo_receiver.rs (90%) rename src/{backend => receivers}/atomic_receiver.rs (86%) rename src/{backend => receivers}/gcda_receiver.rs (89%) rename src/{backend => receivers}/perfetto_receiver.rs (92%) diff --git a/configs/baremetal_firesim.json b/configs/baremetal_hello/baremetal_firesim.json similarity index 54% rename from configs/baremetal_firesim.json rename to configs/baremetal_hello/baremetal_firesim.json index cd48166..6c3497a 100644 --- a/configs/baremetal_firesim.json +++ b/configs/baremetal_hello/baremetal_firesim.json @@ -5,16 +5,7 @@ "kernel_binary": "", "kernel_jump_label_patch_log": "", "driver_binary_entry_tuples": [], - "header_only": false, - "to_stats": false, - "to_txt": true, - "to_stack_txt": false, - "to_atomics": false, - "to_afdo": false, - "gcno": "", - "to_gcda": false, - "to_speedscope": false, - "to_perfetto": false, - "to_foc": false, - "to_vbb": false + "receivers": { + "txt": { "enabled": true, "path": "trace.trace_hello.txt" } + } } diff --git a/configs/baremetal_hello_boom.json b/configs/baremetal_hello/baremetal_hello_boom.json similarity index 53% rename from configs/baremetal_hello_boom.json rename to configs/baremetal_hello/baremetal_hello_boom.json index cf65fc0..0e1391b 100644 --- a/configs/baremetal_hello_boom.json +++ b/configs/baremetal_hello/baremetal_hello_boom.json @@ -5,16 +5,7 @@ "kernel_binary": "", "kernel_jump_label_patch_log": "", "driver_binary_entry_tuples": [], - "header_only": false, - "to_stats": false, - "to_txt": true, - "to_stack_txt": false, - "to_atomics": false, - "to_afdo": false, - "gcno": "", - "to_gcda": false, - "to_speedscope": false, - "to_perfetto": false, - "to_foc": false, - "to_vbb": false + "receivers": { + "txt": { "enabled": true, "path": "trace.trace_hello.txt" } + } } diff --git a/configs/baremetal_hello_spike.json b/configs/baremetal_hello/baremetal_hello_spike.json similarity index 52% rename from configs/baremetal_hello_spike.json rename to configs/baremetal_hello/baremetal_hello_spike.json index 1fcbf40..760ba04 100644 --- a/configs/baremetal_hello_spike.json +++ b/configs/baremetal_hello/baremetal_hello_spike.json @@ -5,16 +5,7 @@ "kernel_binary": "", "kernel_jump_label_patch_log": "", "driver_binary_entry_tuples": [], - "header_only": false, - "to_stats": false, - "to_txt": true, - "to_stack_txt": false, - "to_atomics": false, - "to_afdo": false, - "gcno": "", - "to_gcda": false, - "to_speedscope": true, - "to_perfetto": false, - "to_foc": false, - "to_vbb": false + "receivers": { + "txt": { "enabled": true, "path": "trace.trace_hello.txt" } + } } diff --git a/configs/baremetal.json b/configs/baremetal_hello/baremetal_rocket.json similarity index 53% rename from configs/baremetal.json rename to configs/baremetal_hello/baremetal_rocket.json index d15a612..4ddac91 100644 --- a/configs/baremetal.json +++ b/configs/baremetal_hello/baremetal_rocket.json @@ -5,16 +5,7 @@ "kernel_binary": "", "kernel_jump_label_patch_log": "", "driver_binary_entry_tuples": [], - "header_only": false, - "to_stats": false, - "to_txt": false, - "to_stack_txt": false, - "to_atomics": false, - "to_afdo": false, - "gcno": "", - "to_gcda": false, - "to_speedscope": true, - "to_perfetto": false, - "to_foc": false, - "to_vbb": false + "receivers": { + "speedscope": { "enabled": true, "path": "trace.rocket.speedscope.json" } + } } diff --git a/configs/baremetal_crc32.json b/configs/embench/baremetal_crc32.json similarity index 53% rename from configs/baremetal_crc32.json rename to configs/embench/baremetal_crc32.json index ae7d69b..1cc040a 100644 --- a/configs/baremetal_crc32.json +++ b/configs/embench/baremetal_crc32.json @@ -5,16 +5,5 @@ "kernel_binary": "", "kernel_jump_label_patch_log": "", "driver_binary_entry_tuples": [], - "header_only": false, - "to_stats": false, - "to_txt": false, - "to_stack_txt": false, - "to_atomics": false, - "to_afdo": false, - "gcno": "", - "to_gcda": false, - "to_speedscope": false, - "to_perfetto": false, - "to_foc": false, - "to_vbb": false + "receivers": {} } diff --git a/configs/baremetal_edn.json b/configs/embench/baremetal_edn.json similarity index 100% rename from configs/baremetal_edn.json rename to configs/embench/baremetal_edn.json diff --git a/configs/baremetal_huffbench.json b/configs/embench/baremetal_huffbench.json similarity index 53% rename from configs/baremetal_huffbench.json rename to configs/embench/baremetal_huffbench.json index 8624450..7b0bbeb 100644 --- a/configs/baremetal_huffbench.json +++ b/configs/embench/baremetal_huffbench.json @@ -5,16 +5,5 @@ "kernel_binary": "", "kernel_jump_label_patch_log": "", "driver_binary_entry_tuples": [], - "header_only": false, - "to_stats": false, - "to_txt": false, - "to_stack_txt": false, - "to_atomics": false, - "to_afdo": false, - "gcno": "", - "to_gcda": false, - "to_speedscope": false, - "to_perfetto": false, - "to_foc": false, - "to_vbb": false + "receivers": {} } diff --git a/configs/baremetal_nettlesha256.json b/configs/embench/baremetal_nettlesha256.json similarity index 54% rename from configs/baremetal_nettlesha256.json rename to configs/embench/baremetal_nettlesha256.json index ce1b580..1f37431 100644 --- a/configs/baremetal_nettlesha256.json +++ b/configs/embench/baremetal_nettlesha256.json @@ -5,16 +5,5 @@ "kernel_binary": "", "kernel_jump_label_patch_log": "", "driver_binary_entry_tuples": [], - "header_only": false, - "to_stats": true, - "to_txt": false, - "to_stack_txt": false, - "to_atomics": false, - "to_afdo": false, - "gcno": "", - "to_gcda": false, - "to_speedscope": true, - "to_perfetto": false, - "to_foc": false, - "to_vbb": false + "receivers": {} } diff --git a/configs/baremetal_wikisort.json b/configs/embench/baremetal_wikisort.json similarity index 53% rename from configs/baremetal_wikisort.json rename to configs/embench/baremetal_wikisort.json index da9327a..74315eb 100644 --- a/configs/baremetal_wikisort.json +++ b/configs/embench/baremetal_wikisort.json @@ -5,16 +5,5 @@ "kernel_binary": "", "kernel_jump_label_patch_log": "", "driver_binary_entry_tuples": [], - "header_only": false, - "to_stats": false, - "to_txt": false, - "to_stack_txt": false, - "to_atomics": false, - "to_afdo": false, - "gcno": "", - "to_gcda": false, - "to_speedscope": false, - "to_perfetto": false, - "to_foc": false, - "to_vbb": false + "receivers": {} } diff --git a/configs/jump_label_patch_map.txt b/configs/jump_label_patch_map.txt deleted file mode 100644 index d2af044..0000000 --- a/configs/jump_label_patch_map.txt +++ /dev/null @@ -1,4077 +0,0 @@ -ffffffff8001104c,00000013 -ffffffff800110a4,00000013 -ffffffff80012cae,00000013 -ffffffff80012e6a,00000013 -ffffffff8001319a,00000013 -ffffffff800132a4,00000013 -ffffffff80013b4c,00000013 -ffffffff80013b94,00000013 -ffffffff80013e80,00000013 -ffffffff80014398,00000013 -ffffffff8001c328,00000013 -ffffffff8001c36a,00000013 -ffffffff8001c59c,00000013 -ffffffff8001c670,00000013 -ffffffff809ce1fc,00000013 -ffffffff809ce41c,00000013 -ffffffff800033f4,00000013 -ffffffff8000b8c0,00000013 -ffffffff8000e4c0,00000013 -ffffffff800215d8,00000013 -ffffffff80021ea8,00000013 -ffffffff80021f80,00000013 -ffffffff800220e4,00000013 -ffffffff80022204,00000013 -ffffffff8002237c,00000013 -ffffffff8002249c,00000013 -ffffffff80022658,00000013 -ffffffff80023080,00000013 -ffffffff80023158,00000013 -ffffffff800232a0,00000013 -ffffffff80023448,00000013 -ffffffff800234d8,00000013 -ffffffff800236d8,00000013 -ffffffff800238a8,00000013 -ffffffff80023f70,00000013 -ffffffff800247c0,00000013 -ffffffff80024e78,00000013 -ffffffff80024f0c,00000013 -ffffffff800250c4,00000013 -ffffffff800255a4,00000013 -ffffffff80025624,00000013 -ffffffff800287f0,00000013 -ffffffff8002948c,00000013 -ffffffff800296e4,00000013 -ffffffff800298c4,00000013 -ffffffff80029900,00000013 -ffffffff80029ac4,00000013 -ffffffff8002a484,00000013 -ffffffff8002a700,00000013 -ffffffff8002a8b0,00000013 -ffffffff80031dd8,00000013 -ffffffff80032144,00000013 -ffffffff800323dc,00000013 -ffffffff80032448,00000013 -ffffffff80032508,00000013 -ffffffff800326d4,00000013 -ffffffff800327ec,00000013 -ffffffff8003287c,00000013 -ffffffff800331c8,00000013 -ffffffff80033408,00000013 -ffffffff80033c30,00000013 -ffffffff80033db8,00000013 -ffffffff80033ed4,00000013 -ffffffff80034dd4,00000013 -ffffffff80034e88,00000013 -ffffffff80034f94,00000013 -ffffffff80035078,00000013 -ffffffff800351f4,00000013 -ffffffff800353a8,00000013 -ffffffff80035654,00000013 -ffffffff800356f0,00000013 -ffffffff80036bd4,00000013 -ffffffff80036c7c,00000013 -ffffffff80036d64,00000013 -ffffffff80036e5c,00000013 -ffffffff80038368,00000013 -ffffffff800385d4,00000013 -ffffffff8003870c,00000013 -ffffffff800388e0,00000013 -ffffffff80038af4,00000013 -ffffffff80038ebc,00000013 -ffffffff80038f98,00000013 -ffffffff800390f0,00000013 -ffffffff80039178,00000013 -ffffffff80039218,00000013 -ffffffff80039324,00000013 -ffffffff800393e8,00000013 -ffffffff800394a4,00000013 -ffffffff8003a3d0,00000013 -ffffffff8003a5b4,00000013 -ffffffff8003be60,00000013 -ffffffff8003bf78,00000013 -ffffffff8003c64c,00000013 -ffffffff8003ca88,00000013 -ffffffff8003faf0,00000013 -ffffffff8003fbe4,00000013 -ffffffff8003fc94,00000013 -ffffffff8003fd18,00000013 -ffffffff8004108c,00000013 -ffffffff8004212c,00000013 -ffffffff80042230,00000013 -ffffffff800423b0,00000013 -ffffffff800423ec,00000013 -ffffffff80042644,00000013 -ffffffff800427c4,00000013 -ffffffff8004286c,00000013 -ffffffff80042d0c,00000013 -ffffffff80042e64,00000013 -ffffffff80042eac,00000013 -ffffffff80042f04,00000013 -ffffffff80042f40,00000013 -ffffffff80043108,00000013 -ffffffff80043188,00000013 -ffffffff8004335c,00000013 -ffffffff80043658,00000013 -ffffffff80043888,00000013 -ffffffff80043b60,00000013 -ffffffff80043c5c,00000013 -ffffffff80043ca0,00000013 -ffffffff80043d64,00000013 -ffffffff80043dbc,00000013 -ffffffff800441a8,00000013 -ffffffff80044208,00000013 -ffffffff80044350,00000013 -ffffffff80044568,00000013 -ffffffff800445a0,00000013 -ffffffff80044bf8,00000013 -ffffffff80044d64,00000013 -ffffffff80045010,00000013 -ffffffff80045088,00000013 -ffffffff800452d4,00000013 -ffffffff800453b8,00000013 -ffffffff800468e4,00000013 -ffffffff800469cc,00000013 -ffffffff80046a20,00000013 -ffffffff800471fc,00000013 -ffffffff80047310,00000013 -ffffffff80047378,00000013 -ffffffff800474f4,00000013 -ffffffff8004760c,00000013 -ffffffff80047dfc,00000013 -ffffffff80047ed8,00000013 -ffffffff80047f54,00000013 -ffffffff80048064,00000013 -ffffffff800483bc,00000013 -ffffffff80048790,00000013 -ffffffff800488d4,00000013 -ffffffff800498c8,00000013 -ffffffff80049aa8,00000013 -ffffffff80049bd4,00000013 -ffffffff80049cfc,00000013 -ffffffff80049d8c,00000013 -ffffffff80049e5c,00000013 -ffffffff8004a958,00000013 -ffffffff8004b904,00000013 -ffffffff8004ba58,00000013 -ffffffff8004c2a0,00000013 -ffffffff8004cc80,00000013 -ffffffff8004cd78,00000013 -ffffffff8004cecc,00000013 -ffffffff8004d260,00000013 -ffffffff8004d78c,00000013 -ffffffff8004d88c,00000013 -ffffffff8004dd28,00000013 -ffffffff8004dda8,00000013 -ffffffff8004f5c8,00000013 -ffffffff8004f98c,00000013 -ffffffff80053438,00000013 -ffffffff800536f4,00000013 -ffffffff80053744,00000013 -ffffffff8005a4bc,00000013 -ffffffff8005a57c,00000013 -ffffffff8005a6a0,00000013 -ffffffff8005a9bc,00000013 -ffffffff8005b0c4,00000013 -ffffffff8005b280,00000013 -ffffffff8005b358,00000013 -ffffffff8005b768,00000013 -ffffffff8005b7e4,00000013 -ffffffff8005b8bc,00000013 -ffffffff8005ba1c,00000013 -ffffffff8005bb40,00000013 -ffffffff8005bd18,00000013 -ffffffff8005bf6c,00000013 -ffffffff8005c264,00000013 -ffffffff8005c680,00000013 -ffffffff8005ca20,00000013 -ffffffff8005cb48,00000013 -ffffffff8005d19c,00000013 -ffffffff8005d3cc,00000013 -ffffffff8005d4ac,00000013 -ffffffff8005d7ec,00000013 -ffffffff8005dd84,00000013 -ffffffff8005e0e0,00000013 -ffffffff8005e5b0,00000013 -ffffffff8005e748,00000013 -ffffffff8005e9a4,00000013 -ffffffff8005edc8,00000013 -ffffffff8005f2a8,00000013 -ffffffff8005f48c,00000013 -ffffffff8005f524,00000013 -ffffffff8005f620,00000013 -ffffffff8005f70c,00000013 -ffffffff8005f96c,00000013 -ffffffff8005fc80,00000013 -ffffffff8005fe90,00000013 -ffffffff8005ff98,00000013 -ffffffff800601bc,00000013 -ffffffff800601f0,00000013 -ffffffff800604e8,00000013 -ffffffff80060840,00000013 -ffffffff80060bd8,00000013 -ffffffff80060ca8,00000013 -ffffffff80060f40,00000013 -ffffffff80060f78,00000013 -ffffffff80061080,00000013 -ffffffff8006127c,00000013 -ffffffff80061494,00000013 -ffffffff800615d8,00000013 -ffffffff80062c3c,00000013 -ffffffff800647fc,00000013 -ffffffff80065578,00000013 -ffffffff80065b34,00000013 -ffffffff80067604,00000013 -ffffffff800677e0,00000013 -ffffffff80068bd8,00000013 -ffffffff800691c8,00000013 -ffffffff8006d898,00000013 -ffffffff8006e48c,00000013 -ffffffff8006f244,00000013 -ffffffff8006f670,00000013 -ffffffff800705b8,00000013 -ffffffff80070e24,00000013 -ffffffff80070ea0,00000013 -ffffffff8007419c,00000013 -ffffffff80074300,00000013 -ffffffff80074600,00000013 -ffffffff80074ca8,00000013 -ffffffff8007b00c,00000013 -ffffffff8007b0f0,00000013 -ffffffff8007b1fc,00000013 -ffffffff8007b2a8,00000013 -ffffffff8007b538,00000013 -ffffffff8007c070,00000013 -ffffffff80080334,00000013 -ffffffff8008050c,00000013 -ffffffff80082520,00000013 -ffffffff800825cc,00000013 -ffffffff80084dcc,00000013 -ffffffff80084e74,00000013 -ffffffff80085970,00000013 -ffffffff80085a00,00000013 -ffffffff8008661c,00000013 -ffffffff8008a2b8,00000013 -ffffffff8008a564,00000013 -ffffffff8008a614,00000013 -ffffffff8008a6f0,00000013 -ffffffff8008a7b4,00000013 -ffffffff8008a854,00000013 -ffffffff8008b13c,00000013 -ffffffff8008bcec,00000013 -ffffffff8008bf40,00000013 -ffffffff8008c048,00000013 -ffffffff8008c0f0,00000013 -ffffffff8008cd90,00000013 -ffffffff8008e09c,00000013 -ffffffff8008e23c,00000013 -ffffffff8008e624,00000013 -ffffffff8008e674,00000013 -ffffffff8008e744,00000013 -ffffffff8008e864,00000013 -ffffffff8008ed4c,00000013 -ffffffff8008eda4,00000013 -ffffffff8008ee38,00000013 -ffffffff8008f25c,00000013 -ffffffff8008f2c4,00000013 -ffffffff8008f3ec,00000013 -ffffffff8008f47c,00000013 -ffffffff8008f654,00000013 -ffffffff8008f6c8,00000013 -ffffffff8008f890,00000013 -ffffffff8008f948,00000013 -ffffffff8008fb60,00000013 -ffffffff8008fbd0,00000013 -ffffffff800930f0,00000013 -ffffffff800932dc,00000013 -ffffffff800939ec,00000013 -ffffffff80093c00,00000013 -ffffffff80093fb4,00000013 -ffffffff80094118,00000013 -ffffffff80095330,00000013 -ffffffff800953b0,00000013 -ffffffff8009e4fc,00000013 -ffffffff8009e624,00000013 -ffffffff8009e6f0,00000013 -ffffffff8009fb04,00000013 -ffffffff8009fdf4,00000013 -ffffffff8009ff04,00000013 -ffffffff8009ffe4,00000013 -ffffffff800a034c,00000013 -ffffffff800a03e0,00000013 -ffffffff800a0484,00000013 -ffffffff800a05e8,00000013 -ffffffff800a06c4,00000013 -ffffffff800a0868,00000013 -ffffffff800a0954,00000013 -ffffffff800a09e8,00000013 -ffffffff800a0b58,00000013 -ffffffff800a0c04,00000013 -ffffffff800a0c84,00000013 -ffffffff800a0d90,00000013 -ffffffff800a3f94,00000013 -ffffffff800a4a04,00000013 -ffffffff800a4ac0,00000013 -ffffffff800a4c2c,00000013 -ffffffff800a502c,00000013 -ffffffff800a5248,00000013 -ffffffff800a52a4,00000013 -ffffffff800a5390,00000013 -ffffffff800a5438,00000013 -ffffffff800a5b10,00000013 -ffffffff800a5b98,00000013 -ffffffff800a5e80,00000013 -ffffffff800a6794,00000013 -ffffffff800a6860,00000013 -ffffffff800a6b38,00000013 -ffffffff800a7088,00000013 -ffffffff800a71f8,00000013 -ffffffff800a736c,00000013 -ffffffff800a7b20,00000013 -ffffffff800a7b80,00000013 -ffffffff800a7c34,00000013 -ffffffff800a7c4c,00000013 -ffffffff800a7d54,00000013 -ffffffff800a7fc4,00000013 -ffffffff800a80c0,00000013 -ffffffff800a86c4,00000013 -ffffffff800a8938,00000013 -ffffffff800a8a30,00000013 -ffffffff800a8ae0,00000013 -ffffffff800a8af8,00000013 -ffffffff800a8c78,00000013 -ffffffff800a8cec,00000013 -ffffffff800a9498,00000013 -ffffffff800a9544,00000013 -ffffffff800b7660,00000013 -ffffffff800b7740,00000013 -ffffffff800b77c4,00000013 -ffffffff800ba15c,00000013 -ffffffff800ba1a8,00000013 -ffffffff800ba2a8,00000013 -ffffffff800be724,00000013 -ffffffff800be7ac,00000013 -ffffffff800beb1c,00000013 -ffffffff800beda8,00000013 -ffffffff800bef54,00000013 -ffffffff800bef8c,00000013 -ffffffff800bf1b4,00000013 -ffffffff800bf354,00000013 -ffffffff800bf388,00000013 -ffffffff800bf4d4,00000013 -ffffffff800bf860,00000013 -ffffffff800bf8a4,00000013 -ffffffff800c0660,00000013 -ffffffff800c083c,00000013 -ffffffff800c08a4,00000013 -ffffffff800c15a4,00000013 -ffffffff800c15e4,00000013 -ffffffff800c8934,00000013 -ffffffff800c8b00,00000013 -ffffffff800c8ba0,00000013 -ffffffff800c8c50,00000013 -ffffffff800c8cdc,00000013 -ffffffff800c8dd0,00000013 -ffffffff800c8e1c,00000013 -ffffffff800c8f34,00000013 -ffffffff800c8fb8,00000013 -ffffffff800c9300,00000013 -ffffffff800c934c,00000013 -ffffffff800c94cc,00000013 -ffffffff800c9578,00000013 -ffffffff800c9928,00000013 -ffffffff800c9bac,00000013 -ffffffff800c9c80,00000013 -ffffffff800c9cf4,00000013 -ffffffff800cb484,00000013 -ffffffff800cb6b0,00000013 -ffffffff800cb778,00000013 -ffffffff800cb7d0,00000013 -ffffffff800cb848,00000013 -ffffffff800cb8ac,00000013 -ffffffff800cc4bc,00000013 -ffffffff800cc674,00000013 -ffffffff800cc7e0,00000013 -ffffffff800cc8e4,00000013 -ffffffff800cca08,00000013 -ffffffff800cd3e8,00000013 -ffffffff800cd4c8,00000013 -ffffffff800cd6b8,00000013 -ffffffff800cdc34,00000013 -ffffffff800cdd64,00000013 -ffffffff800ce4e0,00000013 -ffffffff800ce5f8,00000013 -ffffffff800cea30,00000013 -ffffffff800ceab4,00000013 -ffffffff800cebb4,00000013 -ffffffff800ceed4,00000013 -ffffffff800cf068,00000013 -ffffffff800cf47c,00000013 -ffffffff800cf868,00000013 -ffffffff800d0844,00000013 -ffffffff800d08a0,00000013 -ffffffff800d110c,00000013 -ffffffff800d2c30,00000013 -ffffffff800d2d7c,00000013 -ffffffff800d2db0,00000013 -ffffffff800d3010,00000013 -ffffffff800d32b4,00000013 -ffffffff800d34ac,00000013 -ffffffff800d34e4,00000013 -ffffffff800d39d0,00000013 -ffffffff800d3a50,00000013 -ffffffff800d3b00,00000013 -ffffffff800d3ca0,00000013 -ffffffff800d3d34,00000013 -ffffffff800d3e00,00000013 -ffffffff800d3f14,00000013 -ffffffff800d413c,00000013 -ffffffff800d42cc,00000013 -ffffffff800d48e8,00000013 -ffffffff800d49a8,00000013 -ffffffff800d57a4,00000013 -ffffffff800d5828,00000013 -ffffffff800d5860,00000013 -ffffffff800d5898,00000013 -ffffffff800d58f8,00000013 -ffffffff800d5958,00000013 -ffffffff800d59b0,00000013 -ffffffff800d59e4,00000013 -ffffffff800d6818,00000013 -ffffffff800d68f8,00000013 -ffffffff800d6954,00000013 -ffffffff800d69f4,00000013 -ffffffff800d6af8,00000013 -ffffffff800d6c14,00000013 -ffffffff800d7d94,00000013 -ffffffff800d7e0c,00000013 -ffffffff800d7f1c,00000013 -ffffffff800d7f5c,00000013 -ffffffff800d81cc,00000013 -ffffffff800d8308,00000013 -ffffffff800d86a4,00000013 -ffffffff800d874c,00000013 -ffffffff800d87c8,00000013 -ffffffff800d88c8,00000013 -ffffffff800d8ad0,00000013 -ffffffff800d8b24,00000013 -ffffffff800d8bec,00000013 -ffffffff800d8ed4,00000013 -ffffffff800d8f18,00000013 -ffffffff800d8fa4,00000013 -ffffffff800d90b4,00000013 -ffffffff800d9178,00000013 -ffffffff800d94cc,00000013 -ffffffff800d9518,00000013 -ffffffff800d9870,00000013 -ffffffff800d98bc,00000013 -ffffffff800d9ab0,00000013 -ffffffff800d9afc,00000013 -ffffffff800d9b64,00000013 -ffffffff800d9bb0,00000013 -ffffffff800da014,00000013 -ffffffff800da0a0,00000013 -ffffffff800da13c,00000013 -ffffffff800da630,00000013 -ffffffff800da808,00000013 -ffffffff800da84c,00000013 -ffffffff800daa74,00000013 -ffffffff800daab8,00000013 -ffffffff800dae64,00000013 -ffffffff800db220,00000013 -ffffffff800e1e10,00000013 -ffffffff800e20ec,00000013 -ffffffff800e21a0,00000013 -ffffffff800e2994,00000013 -ffffffff800e2ba4,00000013 -ffffffff800e2f10,00000013 -ffffffff800e31bc,00000013 -ffffffff800e3240,00000013 -ffffffff800e3a20,00000013 -ffffffff800e3c7c,00000013 -ffffffff800e3f1c,00000013 -ffffffff800e4964,00000013 -ffffffff800e4ab0,00000013 -ffffffff800e4d54,00000013 -ffffffff800e4eb0,00000013 -ffffffff800e5050,00000013 -ffffffff800e5230,00000013 -ffffffff800e535c,00000013 -ffffffff800e576c,00000013 -ffffffff800e5d30,00000013 -ffffffff800e6188,00000013 -ffffffff800e6ad4,00000013 -ffffffff800e6e50,00000013 -ffffffff800e729c,00000013 -ffffffff800e7368,00000013 -ffffffff800e7948,00000013 -ffffffff800e7e44,00000013 -ffffffff800e809c,00000013 -ffffffff800e8284,00000013 -ffffffff800e83b8,00000013 -ffffffff800e85cc,00000013 -ffffffff800e886c,00000013 -ffffffff800e9844,00000013 -ffffffff800e9f44,00000013 -ffffffff800ea2e8,00000013 -ffffffff800ea3f8,00000013 -ffffffff800eb1d0,00000013 -ffffffff800eb2f0,00000013 -ffffffff800eb3dc,00000013 -ffffffff800eb530,00000013 -ffffffff800eb87c,00000013 -ffffffff800ebf40,00000013 -ffffffff800ec460,00000013 -ffffffff800ec9d8,00000013 -ffffffff800eca88,00000013 -ffffffff800ecc90,00000013 -ffffffff800ecd64,00000013 -ffffffff800ece10,00000013 -ffffffff800eed4c,00000013 -ffffffff800eee24,00000013 -ffffffff800ef310,00000013 -ffffffff800ef550,00000013 -ffffffff800ef6e0,00000013 -ffffffff800ef7bc,00000013 -ffffffff800ef8d0,00000013 -ffffffff800efed0,00000013 -ffffffff800f00fc,00000013 -ffffffff800f03cc,00000013 -ffffffff800f097c,00000013 -ffffffff800f0e00,00000013 -ffffffff800f0fe4,00000013 -ffffffff800f127c,00000013 -ffffffff800f1548,00000013 -ffffffff800f192c,00000013 -ffffffff800f1bb4,00000013 -ffffffff800f1f0c,00000013 -ffffffff800f2014,00000013 -ffffffff800f2268,00000013 -ffffffff800f2494,00000013 -ffffffff800f2b94,00000013 -ffffffff800f4d0c,00000013 -ffffffff800f4ed4,00000013 -ffffffff800f5454,00000013 -ffffffff800f5a54,00000013 -ffffffff800f5a88,00000013 -ffffffff800fc93c,00000013 -ffffffff800ffb84,00000013 -ffffffff80100094,00000013 -ffffffff80100168,00000013 -ffffffff80100294,00000013 -ffffffff801003f4,00000013 -ffffffff801004c0,00000013 -ffffffff801005ac,00000013 -ffffffff8010065c,00000013 -ffffffff80100924,00000013 -ffffffff801009bc,00000013 -ffffffff80100bf0,00000013 -ffffffff80100c80,00000013 -ffffffff80100d40,00000013 -ffffffff80100e1c,00000013 -ffffffff80100f7c,00000013 -ffffffff80100fd8,00000013 -ffffffff8010103c,00000013 -ffffffff801010fc,00000013 -ffffffff80101328,00000013 -ffffffff801013e8,00000013 -ffffffff801015e0,00000013 -ffffffff80101ae4,00000013 -ffffffff80101ee4,00000013 -ffffffff80102058,00000013 -ffffffff80102ccc,00000013 -ffffffff80103988,00000013 -ffffffff80103a00,00000013 -ffffffff80103de0,00000013 -ffffffff80103ecc,00000013 -ffffffff80103f88,00000013 -ffffffff80104208,00000013 -ffffffff80104310,00000013 -ffffffff801043d8,00000013 -ffffffff80104530,00000013 -ffffffff8010457c,00000013 -ffffffff801045a0,00000013 -ffffffff8010469c,00000013 -ffffffff80105870,00000013 -ffffffff801058b8,00000013 -ffffffff801061ac,00000013 -ffffffff80106200,00000013 -ffffffff80106468,00000013 -ffffffff801064b8,00000013 -ffffffff801065e4,00000013 -ffffffff80106d2c,00000013 -ffffffff80106e20,00000013 -ffffffff80107028,00000013 -ffffffff80107078,00000013 -ffffffff80107744,00000013 -ffffffff801078b0,00000013 -ffffffff80107d98,00000013 -ffffffff80107fb0,00000013 -ffffffff80108ec4,00000013 -ffffffff801098c0,00000013 -ffffffff801099a4,00000013 -ffffffff8010d2b0,00000013 -ffffffff8010d304,00000013 -ffffffff8010ec54,00000013 -ffffffff8010eca8,00000013 -ffffffff80115dfc,00000013 -ffffffff80115e64,00000013 -ffffffff8011b708,00000013 -ffffffff8011b7fc,00000013 -ffffffff8011be98,00000013 -ffffffff8011c130,00000013 -ffffffff8011c1ac,00000013 -ffffffff8011c3f8,00000013 -ffffffff8011c478,00000013 -ffffffff8011c674,00000013 -ffffffff8011c968,00000013 -ffffffff8011ca14,00000013 -ffffffff8011caa8,00000013 -ffffffff8011cb04,00000013 -ffffffff8013726c,00000013 -ffffffff8013e5ac,00000013 -ffffffff80169800,00000013 -ffffffff80169d78,00000013 -ffffffff8016a244,00000013 -ffffffff8016a328,00000013 -ffffffff8016a420,00000013 -ffffffff8016a53c,00000013 -ffffffff8016ab3c,00000013 -ffffffff8016b3a4,00000013 -ffffffff8016b4a8,00000013 -ffffffff8016b6f4,00000013 -ffffffff8016b9ec,00000013 -ffffffff8016c6d4,00000013 -ffffffff80179e24,00000013 -ffffffff8017ea50,00000013 -ffffffff8017ebac,00000013 -ffffffff801929b4,00000013 -ffffffff80192f60,00000013 -ffffffff8019419c,00000013 -ffffffff80194418,00000013 -ffffffff8019510c,00000013 -ffffffff801a7d28,00000013 -ffffffff801a8088,00000013 -ffffffff801a80cc,00000013 -ffffffff801a8940,00000013 -ffffffff801a8ab8,00000013 -ffffffff801a8b20,00000013 -ffffffff801a8c70,00000013 -ffffffff801a8ce0,00000013 -ffffffff801a8ea0,00000013 -ffffffff801a9518,00000013 -ffffffff801a9634,00000013 -ffffffff801a9cfc,00000013 -ffffffff801a9fa8,00000013 -ffffffff801aa0f4,00000013 -ffffffff801aa18c,00000013 -ffffffff801aa384,00000013 -ffffffff801aa944,00000013 -ffffffff801aa9a0,00000013 -ffffffff801aaa44,00000013 -ffffffff801ab284,00000013 -ffffffff801ab33c,00000013 -ffffffff801abe5c,00000013 -ffffffff801ac7f4,00000013 -ffffffff801ac858,00000013 -ffffffff801ac890,00000013 -ffffffff801ac904,00000013 -ffffffff801ae14c,00000013 -ffffffff801ae1e0,00000013 -ffffffff801aeadc,00000013 -ffffffff801b088c,00000013 -ffffffff801b1878,00000013 -ffffffff801b1ba0,00000013 -ffffffff801b1c4c,00000013 -ffffffff801b1d6c,00000013 -ffffffff801b1df4,00000013 -ffffffff801b1edc,00000013 -ffffffff801b43d8,00000013 -ffffffff801b80ec,00000013 -ffffffff801ba25c,00000013 -ffffffff801baed4,00000013 -ffffffff801bafb8,00000013 -ffffffff801bb19c,00000013 -ffffffff801bb47c,00000013 -ffffffff801bb4d8,00000013 -ffffffff801bb5f8,00000013 -ffffffff801bb7ac,00000013 -ffffffff801c04c4,00000013 -ffffffff801c06fc,00000013 -ffffffff801c0c7c,00000013 -ffffffff801c118c,00000013 -ffffffff801c15a8,00000013 -ffffffff801c1780,00000013 -ffffffff801c1c00,00000013 -ffffffff801c1fc4,00000013 -ffffffff801c226c,00000013 -ffffffff801c22bc,00000013 -ffffffff801c24f0,00000013 -ffffffff801c2548,00000013 -ffffffff801c2ba0,00000013 -ffffffff801c37c4,00000013 -ffffffff801c3800,00000013 -ffffffff801c4498,00000013 -ffffffff801c741c,00000013 -ffffffff801c7b0c,00000013 -ffffffff801c7c4c,00000013 -ffffffff801c7d10,00000013 -ffffffff801c8038,00000013 -ffffffff801c8274,00000013 -ffffffff801c83a0,00000013 -ffffffff801c8658,00000013 -ffffffff801c86c0,00000013 -ffffffff801c8e14,00000013 -ffffffff801ca2c0,00000013 -ffffffff801ca424,00000013 -ffffffff801ca570,00000013 -ffffffff801ca644,00000013 -ffffffff801cccc0,00000013 -ffffffff801d0244,00000013 -ffffffff801d0bbc,00000013 -ffffffff801d0c0c,00000013 -ffffffff801d0e14,00000013 -ffffffff801d0e64,00000013 -ffffffff801d14b8,00000013 -ffffffff801d18f0,00000013 -ffffffff801d1944,00000013 -ffffffff801d19e0,00000013 -ffffffff801d1a20,00000013 -ffffffff801d4e84,00000013 -ffffffff801d5180,00000013 -ffffffff801d53b4,00000013 -ffffffff801d5944,00000013 -ffffffff801d599c,00000013 -ffffffff801d5a50,00000013 -ffffffff801d5ae0,00000013 -ffffffff801d5b34,00000013 -ffffffff801d6774,00000013 -ffffffff801d6920,00000013 -ffffffff801d6a10,00000013 -ffffffff801d6bb8,00000013 -ffffffff801d6d6c,00000013 -ffffffff801d7700,00000013 -ffffffff801d7804,00000013 -ffffffff801d91b4,00000013 -ffffffff801db29c,00000013 -ffffffff801db8a8,00000013 -ffffffff801dbc20,00000013 -ffffffff801dbdb4,00000013 -ffffffff801dbe90,00000013 -ffffffff801dc168,00000013 -ffffffff801dc2a0,00000013 -ffffffff801dc3cc,00000013 -ffffffff801dc460,00000013 -ffffffff801dc5b8,00000013 -ffffffff801dc744,00000013 -ffffffff801dc868,00000013 -ffffffff801dc99c,00000013 -ffffffff801dcb2c,00000013 -ffffffff801dcbd8,00000013 -ffffffff801dcd28,00000013 -ffffffff801dcef0,00000013 -ffffffff801dd03c,00000013 -ffffffff801dd348,00000013 -ffffffff801ddbe8,00000013 -ffffffff801ddc50,00000013 -ffffffff801dde1c,00000013 -ffffffff801ddebc,00000013 -ffffffff801de344,00000013 -ffffffff801debf0,00000013 -ffffffff801dfb30,00000013 -ffffffff801dfc04,00000013 -ffffffff801e026c,00000013 -ffffffff801e0308,00000013 -ffffffff801e03dc,00000013 -ffffffff801e0528,00000013 -ffffffff801e092c,00000013 -ffffffff801e09d4,00000013 -ffffffff801e22bc,00000013 -ffffffff801e2e00,00000013 -ffffffff801e5b44,00000013 -ffffffff801e6094,00000013 -ffffffff801e6158,00000013 -ffffffff801e62b8,00000013 -ffffffff801e6320,00000013 -ffffffff801e63c4,00000013 -ffffffff801e64f8,00000013 -ffffffff801e66e4,00000013 -ffffffff801e6760,00000013 -ffffffff801e67b0,00000013 -ffffffff801e6a04,00000013 -ffffffff801e6ae8,00000013 -ffffffff801e6dcc,00000013 -ffffffff801e9808,00000013 -ffffffff801e98b0,00000013 -ffffffff801e9e8c,00000013 -ffffffff801ea008,00000013 -ffffffff801ea1b8,00000013 -ffffffff801ea2c0,00000013 -ffffffff801ea43c,00000013 -ffffffff801f6880,00000013 -ffffffff801f6acc,00000013 -ffffffff801f6b34,00000013 -ffffffff801f6b6c,00000013 -ffffffff801f6bb4,00000013 -ffffffff801f6e6c,00000013 -ffffffff801f6ee8,00000013 -ffffffff801f6f2c,00000013 -ffffffff801f7094,00000013 -ffffffff801f70f4,00000013 -ffffffff801f712c,00000013 -ffffffff801f72c0,00000013 -ffffffff801f7368,00000013 -ffffffff801f739c,00000013 -ffffffff801f7934,00000013 -ffffffff801f7998,00000013 -ffffffff801f79f4,00000013 -ffffffff801f7a88,00000013 -ffffffff801f7b00,00000013 -ffffffff801f7b34,00000013 -ffffffff801fa460,00000013 -ffffffff801fa558,00000013 -ffffffff801fa7c0,00000013 -ffffffff801faa44,00000013 -ffffffff801faad0,00000013 -ffffffff801fab34,00000013 -ffffffff801faec8,00000013 -ffffffff801fb1dc,00000013 -ffffffff801fe2e4,00000013 -ffffffff801ffb90,00000013 -ffffffff802004cc,00000013 -ffffffff80200554,00000013 -ffffffff80200b44,00000013 -ffffffff80201174,00000013 -ffffffff80201460,00000013 -ffffffff80201648,00000013 -ffffffff80201f3c,00000013 -ffffffff80201fa0,00000013 -ffffffff80202834,00000013 -ffffffff8020515c,00000013 -ffffffff80205258,00000013 -ffffffff80205b50,00000013 -ffffffff80205d50,00000013 -ffffffff80205fbc,00000013 -ffffffff802062b0,00000013 -ffffffff80206f84,00000013 -ffffffff80207ad8,00000013 -ffffffff80207db8,00000013 -ffffffff80208170,00000013 -ffffffff8020829c,00000013 -ffffffff80209304,00000013 -ffffffff80209d70,00000013 -ffffffff8020a1d0,00000013 -ffffffff8020a404,00000013 -ffffffff8020a798,00000013 -ffffffff8020acd8,00000013 -ffffffff8020b1a0,00000013 -ffffffff8020b2a4,00000013 -ffffffff8020d930,00000013 -ffffffff8020e1dc,00000013 -ffffffff8020e2fc,00000013 -ffffffff8020f0b4,00000013 -ffffffff80210188,00000013 -ffffffff80210318,00000013 -ffffffff80210350,00000013 -ffffffff80210484,00000013 -ffffffff802105d0,00000013 -ffffffff80210608,00000013 -ffffffff80211b1c,00000013 -ffffffff80211da0,00000013 -ffffffff80211e20,00000013 -ffffffff80211ecc,00000013 -ffffffff80211f50,00000013 -ffffffff802122d0,00000013 -ffffffff80213084,00000013 -ffffffff802131d0,00000013 -ffffffff802132ac,00000013 -ffffffff80213344,00000013 -ffffffff802133ec,00000013 -ffffffff80213450,00000013 -ffffffff80213838,00000013 -ffffffff80214c48,00000013 -ffffffff80214d0c,00000013 -ffffffff80215860,00000013 -ffffffff802159cc,00000013 -ffffffff80215e78,00000013 -ffffffff802165e8,00000013 -ffffffff802168a4,00000013 -ffffffff80216a7c,00000013 -ffffffff802177e0,00000013 -ffffffff802196d4,00000013 -ffffffff80219868,00000013 -ffffffff802198f8,00000013 -ffffffff80219b70,00000013 -ffffffff80219c30,00000013 -ffffffff80219fa8,00000013 -ffffffff8021a184,00000013 -ffffffff8021a2a8,00000013 -ffffffff8021a3e0,00000013 -ffffffff8021a720,00000013 -ffffffff8021aaa8,00000013 -ffffffff8021ac90,00000013 -ffffffff8021afb8,00000013 -ffffffff8021b174,00000013 -ffffffff8021b6c4,00000013 -ffffffff8021b940,00000013 -ffffffff8021bde0,00000013 -ffffffff8021bf48,00000013 -ffffffff8021c47c,00000013 -ffffffff8021c4f4,00000013 -ffffffff8021c560,00000013 -ffffffff8021c744,00000013 -ffffffff8021c8c8,00000013 -ffffffff8021ccbc,00000013 -ffffffff8021cd2c,00000013 -ffffffff8021ced8,00000013 -ffffffff8021cf68,00000013 -ffffffff8021cfa8,00000013 -ffffffff8021d448,00000013 -ffffffff8021d724,00000013 -ffffffff8021d82c,00000013 -ffffffff8021e1a0,00000013 -ffffffff8021e214,00000013 -ffffffff8021e274,00000013 -ffffffff8021e8b8,00000013 -ffffffff8021fc9c,00000013 -ffffffff8021fd90,00000013 -ffffffff8021fde8,00000013 -ffffffff80220098,00000013 -ffffffff80226ac4,00000013 -ffffffff80227334,00000013 -ffffffff80229cdc,00000013 -ffffffff8022a0cc,00000013 -ffffffff8022a3c0,00000013 -ffffffff8022a450,00000013 -ffffffff8022c3f0,00000013 -ffffffff8022c458,00000013 -ffffffff8022c7d8,00000013 -ffffffff8022caa8,00000013 -ffffffff80237d48,00000013 -ffffffff80237f3c,00000013 -ffffffff80239ddc,00000013 -ffffffff80239eb0,00000013 -ffffffff8023a024,00000013 -ffffffff8023a52c,00000013 -ffffffff8023a760,00000013 -ffffffff8023a9cc,00000013 -ffffffff8023aafc,00000013 -ffffffff8023c7b0,00000013 -ffffffff8023cab4,00000013 -ffffffff8023cc84,00000013 -ffffffff8023e4ac,00000013 -ffffffff8023e570,00000013 -ffffffff8023e6ac,00000013 -ffffffff8023e744,00000013 -ffffffff8023e810,00000013 -ffffffff8023eb44,00000013 -ffffffff8023ec20,00000013 -ffffffff8023ec58,00000013 -ffffffff8023ecc0,00000013 -ffffffff8023ecf8,00000013 -ffffffff8023eec4,00000013 -ffffffff8023ef98,00000013 -ffffffff8023f000,00000013 -ffffffff8023f18c,00000013 -ffffffff8023f270,00000013 -ffffffff8023f540,00000013 -ffffffff8023fd94,00000013 -ffffffff8023ffbc,00000013 -ffffffff80240220,00000013 -ffffffff802404bc,00000013 -ffffffff80240670,00000013 -ffffffff80240760,00000013 -ffffffff80240924,00000013 -ffffffff80240a84,00000013 -ffffffff80240ae0,00000013 -ffffffff80240df4,00000013 -ffffffff80240e70,00000013 -ffffffff80240fe0,00000013 -ffffffff802411e0,00000013 -ffffffff8024123c,00000013 -ffffffff802415e0,00000013 -ffffffff8024177c,00000013 -ffffffff80241854,00000013 -ffffffff80241a00,00000013 -ffffffff80242150,00000013 -ffffffff802421d0,00000013 -ffffffff802424b4,00000013 -ffffffff802425ac,00000013 -ffffffff80242630,00000013 -ffffffff80242668,00000013 -ffffffff802426e8,00000013 -ffffffff80242834,00000013 -ffffffff8024286c,00000013 -ffffffff80242928,00000013 -ffffffff80242a1c,00000013 -ffffffff80242ac0,00000013 -ffffffff80242af8,00000013 -ffffffff80242b70,00000013 -ffffffff80242f24,00000013 -ffffffff8024309c,00000013 -ffffffff8024319c,00000013 -ffffffff802433c0,00000013 -ffffffff80244ca0,00000013 -ffffffff80245374,00000013 -ffffffff802455d8,00000013 -ffffffff802456bc,00000013 -ffffffff802457bc,00000013 -ffffffff802458c0,00000013 -ffffffff80245a5c,00000013 -ffffffff80245bc8,00000013 -ffffffff80245d60,00000013 -ffffffff80245e2c,00000013 -ffffffff80245fb0,00000013 -ffffffff8024604c,00000013 -ffffffff8024613c,00000013 -ffffffff80246260,00000013 -ffffffff802462e8,00000013 -ffffffff802464f8,00000013 -ffffffff802465c4,00000013 -ffffffff802466a0,00000013 -ffffffff802467f4,00000013 -ffffffff802468dc,00000013 -ffffffff80246abc,00000013 -ffffffff80246be0,00000013 -ffffffff80246c84,00000013 -ffffffff80246d38,00000013 -ffffffff80246ebc,00000013 -ffffffff8024773c,00000013 -ffffffff802477a4,00000013 -ffffffff80247860,00000013 -ffffffff80247968,00000013 -ffffffff80247a94,00000013 -ffffffff80247bfc,00000013 -ffffffff80247ef8,00000013 -ffffffff8024816c,00000013 -ffffffff80248220,00000013 -ffffffff8024828c,00000013 -ffffffff802484c8,00000013 -ffffffff80248534,00000013 -ffffffff80248608,00000013 -ffffffff802486c4,00000013 -ffffffff80248738,00000013 -ffffffff80248ac4,00000013 -ffffffff80248c3c,00000013 -ffffffff80248db0,00000013 -ffffffff802492e0,00000013 -ffffffff80249664,00000013 -ffffffff802498f0,00000013 -ffffffff80249c00,00000013 -ffffffff8024a030,00000013 -ffffffff8024a6e8,00000013 -ffffffff8024a728,00000013 -ffffffff8024a98c,00000013 -ffffffff8024a9d0,00000013 -ffffffff8024aba4,00000013 -ffffffff8024b1fc,00000013 -ffffffff8024b244,00000013 -ffffffff8024b700,00000013 -ffffffff8024b7d4,00000013 -ffffffff8024b864,00000013 -ffffffff8024bfd8,00000013 -ffffffff8024c224,00000013 -ffffffff8024c6d0,00000013 -ffffffff8024c770,00000013 -ffffffff8024ca80,00000013 -ffffffff8024cfcc,00000013 -ffffffff8024d388,00000013 -ffffffff8024d53c,00000013 -ffffffff8024d780,00000013 -ffffffff8024d958,00000013 -ffffffff8024da28,00000013 -ffffffff8024dac4,00000013 -ffffffff8024db74,00000013 -ffffffff8024dbf8,00000013 -ffffffff8024dee4,00000013 -ffffffff8024dffc,00000013 -ffffffff8024e100,00000013 -ffffffff8024e264,00000013 -ffffffff8024edb0,00000013 -ffffffff8024ef00,00000013 -ffffffff8024f80c,00000013 -ffffffff8024f954,00000013 -ffffffff8024fa94,00000013 -ffffffff8024fbcc,00000013 -ffffffff8024fc48,00000013 -ffffffff8024fcf4,00000013 -ffffffff8024fd70,00000013 -ffffffff8024fe78,00000013 -ffffffff8024ffc8,00000013 -ffffffff80250064,00000013 -ffffffff802502b4,00000013 -ffffffff80250338,00000013 -ffffffff802503b4,00000013 -ffffffff80250400,00000013 -ffffffff8025056c,00000013 -ffffffff80250664,00000013 -ffffffff80250928,00000013 -ffffffff80251694,00000013 -ffffffff80251908,00000013 -ffffffff80251c78,00000013 -ffffffff80252f58,00000013 -ffffffff80253190,00000013 -ffffffff80253348,00000013 -ffffffff80253408,00000013 -ffffffff8025566c,00000013 -ffffffff80255d9c,00000013 -ffffffff80255e90,00000013 -ffffffff80255ff8,00000013 -ffffffff802560d4,00000013 -ffffffff80257780,00000013 -ffffffff80257950,00000013 -ffffffff8025b4c0,00000013 -ffffffff8025b5f0,00000013 -ffffffff8025b6d8,00000013 -ffffffff8025b790,00000013 -ffffffff8025b804,00000013 -ffffffff8025c4e4,00000013 -ffffffff8025cb8c,00000013 -ffffffff8025d708,00000013 -ffffffff8025d758,00000013 -ffffffff8025d998,00000013 -ffffffff8025da18,00000013 -ffffffff8025e4bc,00000013 -ffffffff8025e5dc,00000013 -ffffffff8025e7d0,00000013 -ffffffff80261e70,00000013 -ffffffff80266a04,00000013 -ffffffff80266ab4,00000013 -ffffffff80266b58,00000013 -ffffffff80266c1c,00000013 -ffffffff80266c94,00000013 -ffffffff80266ea4,00000013 -ffffffff80266f3c,00000013 -ffffffff80267080,00000013 -ffffffff80267104,00000013 -ffffffff80267310,00000013 -ffffffff80267518,00000013 -ffffffff80267ed8,00000013 -ffffffff80267f80,00000013 -ffffffff802680a4,00000013 -ffffffff80268170,00000013 -ffffffff80268254,00000013 -ffffffff802683c0,00000013 -ffffffff80268444,00000013 -ffffffff802689e4,00000013 -ffffffff80268b58,00000013 -ffffffff80268c1c,00000013 -ffffffff80268d30,00000013 -ffffffff80268de0,00000013 -ffffffff80269008,00000013 -ffffffff80269160,00000013 -ffffffff802691bc,00000013 -ffffffff80269e04,00000013 -ffffffff80269ec0,00000013 -ffffffff8026a034,00000013 -ffffffff8026a12c,00000013 -ffffffff8026a348,00000013 -ffffffff8026a4b0,00000013 -ffffffff8026adec,00000013 -ffffffff8026aea4,00000013 -ffffffff8026c600,00000013 -ffffffff8026c714,00000013 -ffffffff8026c980,00000013 -ffffffff8026cb14,00000013 -ffffffff8026d3a8,00000013 -ffffffff8026d404,00000013 -ffffffff8026d694,00000013 -ffffffff8026db24,00000013 -ffffffff8026dbd4,00000013 -ffffffff8026f58c,00000013 -ffffffff8026f658,00000013 -ffffffff8026f734,00000013 -ffffffff8026f7b4,00000013 -ffffffff8026f91c,00000013 -ffffffff8026fb3c,00000013 -ffffffff80270048,00000013 -ffffffff80270110,00000013 -ffffffff80271ea8,00000013 -ffffffff80272028,00000013 -ffffffff802720a4,00000013 -ffffffff80272a3c,00000013 -ffffffff80272c2c,00000013 -ffffffff80272ecc,00000013 -ffffffff80273878,00000013 -ffffffff80275e7c,00000013 -ffffffff80275fdc,00000013 -ffffffff80276a5c,00000013 -ffffffff802780d4,00000013 -ffffffff802783f0,00000013 -ffffffff80279418,00000013 -ffffffff80279454,00000013 -ffffffff802795c4,00000013 -ffffffff80279600,00000013 -ffffffff8027a328,00000013 -ffffffff8027efdc,00000013 -ffffffff8027f07c,00000013 -ffffffff8027f11c,00000013 -ffffffff8027f1b8,00000013 -ffffffff8027f250,00000013 -ffffffff8027f314,00000013 -ffffffff8027f40c,00000013 -ffffffff8027f458,00000013 -ffffffff8027f580,00000013 -ffffffff8027f5ec,00000013 -ffffffff8027f6a4,00000013 -ffffffff8027f7a8,00000013 -ffffffff8027f8a8,00000013 -ffffffff8027f8dc,00000013 -ffffffff8027fa30,00000013 -ffffffff8027fa68,00000013 -ffffffff8027fb80,00000013 -ffffffff8027fbb4,00000013 -ffffffff8027fcac,00000013 -ffffffff8027fd5c,00000013 -ffffffff8027fe04,00000013 -ffffffff8027fe3c,00000013 -ffffffff8027ffa0,00000013 -ffffffff8027ffe4,00000013 -ffffffff80280068,00000013 -ffffffff802801a0,00000013 -ffffffff80280244,00000013 -ffffffff802802bc,00000013 -ffffffff80280524,00000013 -ffffffff802805e8,00000013 -ffffffff80280624,00000013 -ffffffff8028065c,00000013 -ffffffff80280694,00000013 -ffffffff80280764,00000013 -ffffffff80280988,00000013 -ffffffff80280af0,00000013 -ffffffff80280b74,00000013 -ffffffff80280bdc,00000013 -ffffffff80280cf8,00000013 -ffffffff80280d38,00000013 -ffffffff80280d94,00000013 -ffffffff80280e18,00000013 -ffffffff80280e60,00000013 -ffffffff80280f64,00000013 -ffffffff80280fac,00000013 -ffffffff802810bc,00000013 -ffffffff80281190,00000013 -ffffffff80281200,00000013 -ffffffff80281258,00000013 -ffffffff80281368,00000013 -ffffffff802813fc,00000013 -ffffffff8028152c,00000013 -ffffffff8028158c,00000013 -ffffffff80281648,00000013 -ffffffff80281750,00000013 -ffffffff80281784,00000013 -ffffffff80281838,00000013 -ffffffff802819a8,00000013 -ffffffff80281ad4,00000013 -ffffffff80281b50,00000013 -ffffffff80281be4,00000013 -ffffffff80281d3c,00000013 -ffffffff80281da0,00000013 -ffffffff80281e88,00000013 -ffffffff80281f6c,00000013 -ffffffff80281fb4,00000013 -ffffffff80282088,00000013 -ffffffff802820c8,00000013 -ffffffff802822bc,00000013 -ffffffff80282318,00000013 -ffffffff802823f0,00000013 -ffffffff802824b0,00000013 -ffffffff802825f0,00000013 -ffffffff80282640,00000013 -ffffffff80282688,00000013 -ffffffff80282704,00000013 -ffffffff8028280c,00000013 -ffffffff802828b4,00000013 -ffffffff80282c58,00000013 -ffffffff80282d0c,00000013 -ffffffff80282d94,00000013 -ffffffff80282ed8,00000013 -ffffffff80282f5c,00000013 -ffffffff80283130,00000013 -ffffffff802831f4,00000013 -ffffffff802854a0,00000013 -ffffffff8028554c,00000013 -ffffffff80285648,00000013 -ffffffff80285780,00000013 -ffffffff80285834,00000013 -ffffffff80285868,00000013 -ffffffff80285988,00000013 -ffffffff802859bc,00000013 -ffffffff80285a78,00000013 -ffffffff802860e8,00000013 -ffffffff80286144,00000013 -ffffffff80286238,00000013 -ffffffff802862dc,00000013 -ffffffff8028635c,00000013 -ffffffff8028653c,00000013 -ffffffff802865c8,00000013 -ffffffff80286614,00000013 -ffffffff802866d0,00000013 -ffffffff80286810,00000013 -ffffffff80286888,00000013 -ffffffff8028690c,00000013 -ffffffff802869e8,00000013 -ffffffff80286a60,00000013 -ffffffff80286b58,00000013 -ffffffff80286c24,00000013 -ffffffff80286d14,00000013 -ffffffff80286e74,00000013 -ffffffff80286eac,00000013 -ffffffff80286f44,00000013 -ffffffff80286f78,00000013 -ffffffff80287094,00000013 -ffffffff802870e4,00000013 -ffffffff8028711c,00000013 -ffffffff80287248,00000013 -ffffffff80287298,00000013 -ffffffff802874c8,00000013 -ffffffff80287518,00000013 -ffffffff80287600,00000013 -ffffffff8028785c,00000013 -ffffffff80287894,00000013 -ffffffff80287958,00000013 -ffffffff80287994,00000013 -ffffffff80287a00,00000013 -ffffffff80287b90,00000013 -ffffffff80287c4c,00000013 -ffffffff80287cfc,00000013 -ffffffff80287d34,00000013 -ffffffff80287d9c,00000013 -ffffffff80287df8,00000013 -ffffffff80287ffc,00000013 -ffffffff8028839c,00000013 -ffffffff802884e0,00000013 -ffffffff80288514,00000013 -ffffffff80289cb8,00000013 -ffffffff80289dac,00000013 -ffffffff80289e94,00000013 -ffffffff80289fc4,00000013 -ffffffff8028a094,00000013 -ffffffff8028a1a8,00000013 -ffffffff8028a244,00000013 -ffffffff8028a458,00000013 -ffffffff8028a624,00000013 -ffffffff8028a960,00000013 -ffffffff8028abf8,00000013 -ffffffff8028ad04,00000013 -ffffffff8028ae28,00000013 -ffffffff8028afa0,00000013 -ffffffff8028b0c0,00000013 -ffffffff8028b128,00000013 -ffffffff8028b178,00000013 -ffffffff8028b1c8,00000013 -ffffffff8028b284,00000013 -ffffffff8028b390,00000013 -ffffffff8028b470,00000013 -ffffffff8028b568,00000013 -ffffffff8028b650,00000013 -ffffffff8028b920,00000013 -ffffffff8028ba4c,00000013 -ffffffff8028ba9c,00000013 -ffffffff8028cfb8,00000013 -ffffffff8028d058,00000013 -ffffffff8028d13c,00000013 -ffffffff8028d318,00000013 -ffffffff8028d83c,00000013 -ffffffff8028da08,00000013 -ffffffff8028debc,00000013 -ffffffff8028df84,00000013 -ffffffff8028e090,00000013 -ffffffff8028e2a0,00000013 -ffffffff8028e4f4,00000013 -ffffffff8028e6c0,00000013 -ffffffff8028f860,00000013 -ffffffff8028f990,00000013 -ffffffff8029012c,00000013 -ffffffff802901f4,00000013 -ffffffff802907e4,00000013 -ffffffff802909d0,00000013 -ffffffff80290c1c,00000013 -ffffffff80290d14,00000013 -ffffffff80290f64,00000013 -ffffffff802910e4,00000013 -ffffffff802911b0,00000013 -ffffffff802913e0,00000013 -ffffffff8029158c,00000013 -ffffffff802916c8,00000013 -ffffffff80291748,00000013 -ffffffff802919ac,00000013 -ffffffff80291bf4,00000013 -ffffffff80292008,00000013 -ffffffff8029242c,00000013 -ffffffff80292524,00000013 -ffffffff802929d8,00000013 -ffffffff80292b50,00000013 -ffffffff80293034,00000013 -ffffffff802931d4,00000013 -ffffffff802933fc,00000013 -ffffffff8029358c,00000013 -ffffffff80294084,00000013 -ffffffff802944b4,00000013 -ffffffff80294630,00000013 -ffffffff8029477c,00000013 -ffffffff80294824,00000013 -ffffffff80294a30,00000013 -ffffffff80294ed4,00000013 -ffffffff802954a4,00000013 -ffffffff802957f0,00000013 -ffffffff8029a4a8,00000013 -ffffffff8029a56c,00000013 -ffffffff8029a5d4,00000013 -ffffffff8029a6d8,00000013 -ffffffff8029a714,00000013 -ffffffff8029aa1c,00000013 -ffffffff8029aa5c,00000013 -ffffffff8029acfc,00000013 -ffffffff8029ad38,00000013 -ffffffff8029ad7c,00000013 -ffffffff8029affc,00000013 -ffffffff8029b040,00000013 -ffffffff8029b100,00000013 -ffffffff8029b268,00000013 -ffffffff8029b3c4,00000013 -ffffffff8029b518,00000013 -ffffffff8029b584,00000013 -ffffffff8029fd3c,00000013 -ffffffff8029fd50,00000013 -ffffffff8029fdcc,00000013 -ffffffff8029fde0,00000013 -ffffffff8029fe70,00000013 -ffffffff8029ff54,00000013 -ffffffff802a044c,00000013 -ffffffff802a05b0,00000013 -ffffffff802a06dc,00000013 -ffffffff802a080c,00000013 -ffffffff802a0930,00000013 -ffffffff802a0994,00000013 -ffffffff802a0a98,00000013 -ffffffff802a0c28,00000013 -ffffffff802a0c84,00000013 -ffffffff802a0ce4,00000013 -ffffffff802a0d78,00000013 -ffffffff802a0e64,00000013 -ffffffff802a0eb8,00000013 -ffffffff802a1738,00000013 -ffffffff802a1774,00000013 -ffffffff802a18d0,00000013 -ffffffff802a1908,00000013 -ffffffff802a1b64,00000013 -ffffffff802a1bc0,00000013 -ffffffff802a1cb4,00000013 -ffffffff802a1d64,00000013 -ffffffff802a1eb4,00000013 -ffffffff802a1ee8,00000013 -ffffffff802a2830,00000013 -ffffffff802a29e4,00000013 -ffffffff802a2a1c,00000013 -ffffffff802a2aa0,00000013 -ffffffff802a2b00,00000013 -ffffffff802a2cd4,00000013 -ffffffff802a2fc8,00000013 -ffffffff802a3058,00000013 -ffffffff802a3198,00000013 -ffffffff802a329c,00000013 -ffffffff802a32f0,00000013 -ffffffff802a33a4,00000013 -ffffffff802a3550,00000013 -ffffffff802a3660,00000013 -ffffffff802a3810,00000013 -ffffffff802a38d8,00000013 -ffffffff802a3a24,00000013 -ffffffff802a3b94,00000013 -ffffffff802a40b8,00000013 -ffffffff802a4144,00000013 -ffffffff802a4240,00000013 -ffffffff802a434c,00000013 -ffffffff802a456c,00000013 -ffffffff802a4b5c,00000013 -ffffffff802a4eac,00000013 -ffffffff802a8d14,00000013 -ffffffff802a8d60,00000013 -ffffffff802a90f8,00000013 -ffffffff802a97a0,00000013 -ffffffff802a9888,00000013 -ffffffff802a9968,00000013 -ffffffff802a9a14,00000013 -ffffffff802a9be0,00000013 -ffffffff802a9c14,00000013 -ffffffff802a9d24,00000013 -ffffffff802a9dcc,00000013 -ffffffff802a9e00,00000013 -ffffffff802aabf8,00000013 -ffffffff802aaca4,00000013 -ffffffff802aad00,00000013 -ffffffff802aade8,00000013 -ffffffff802aaec0,00000013 -ffffffff802aaf88,00000013 -ffffffff802aaff4,00000013 -ffffffff802adcb8,00000013 -ffffffff802adcec,00000013 -ffffffff802af7a8,00000013 -ffffffff802af8f4,00000013 -ffffffff802b1eec,00000013 -ffffffff802b2020,00000013 -ffffffff802b27ac,00000013 -ffffffff802b286c,00000013 -ffffffff802b2928,00000013 -ffffffff802b2ab8,00000013 -ffffffff802b2f00,00000013 -ffffffff802b32f4,00000013 -ffffffff802b3350,00000013 -ffffffff802b33e8,00000013 -ffffffff802b3458,00000013 -ffffffff802b34c0,00000013 -ffffffff802b3534,00000013 -ffffffff802b3848,00000013 -ffffffff802b3ad8,00000013 -ffffffff802b5858,00000013 -ffffffff802b5890,00000013 -ffffffff802b59a8,00000013 -ffffffff802b5a74,00000013 -ffffffff802b7df8,00000013 -ffffffff802b7f04,00000013 -ffffffff802b7f3c,00000013 -ffffffff802b7fec,00000013 -ffffffff802b8038,00000013 -ffffffff802b8274,00000013 -ffffffff802b82b0,00000013 -ffffffff802b82fc,00000013 -ffffffff802b8560,00000013 -ffffffff802b8654,00000013 -ffffffff802b86c8,00000013 -ffffffff802b872c,00000013 -ffffffff802b8790,00000013 -ffffffff802b87d0,00000013 -ffffffff802b8808,00000013 -ffffffff802b881c,00000013 -ffffffff802b88c0,00000013 -ffffffff802b8908,00000013 -ffffffff802b8970,00000013 -ffffffff802b8b70,00000013 -ffffffff802b8ce8,00000013 -ffffffff802b9004,00000013 -ffffffff802b9164,00000013 -ffffffff802b9258,00000013 -ffffffff802b938c,00000013 -ffffffff802b9470,00000013 -ffffffff802b9590,00000013 -ffffffff802b95c8,00000013 -ffffffff802b9814,00000013 -ffffffff802b98b0,00000013 -ffffffff802b99ac,00000013 -ffffffff802b9b24,00000013 -ffffffff802b9b88,00000013 -ffffffff802b9ce8,00000013 -ffffffff802b9ddc,00000013 -ffffffff802b9f18,00000013 -ffffffff802b9f74,00000013 -ffffffff802ba01c,00000013 -ffffffff802ba084,00000013 -ffffffff802ba20c,00000013 -ffffffff802ba2a4,00000013 -ffffffff802ba570,00000013 -ffffffff802ba638,00000013 -ffffffff802ba8f0,00000013 -ffffffff802baa08,00000013 -ffffffff802bab50,00000013 -ffffffff802badc0,00000013 -ffffffff802bb26c,00000013 -ffffffff802bb40c,00000013 -ffffffff802bb45c,00000013 -ffffffff802bb6e8,00000013 -ffffffff802bb894,00000013 -ffffffff802bba50,00000013 -ffffffff802bbac8,00000013 -ffffffff802bbcd0,00000013 -ffffffff802bbdd8,00000013 -ffffffff802bc0b4,00000013 -ffffffff802bd458,00000013 -ffffffff802bd550,00000013 -ffffffff802bd98c,00000013 -ffffffff802bdc28,00000013 -ffffffff802bde08,00000013 -ffffffff802bdeb0,00000013 -ffffffff802be288,00000013 -ffffffff802bf21c,00000013 -ffffffff802bf310,00000013 -ffffffff802bf3d8,00000013 -ffffffff802bf448,00000013 -ffffffff802bf6c8,00000013 -ffffffff802bfc70,00000013 -ffffffff802bfd9c,00000013 -ffffffff802c002c,00000013 -ffffffff802c0144,00000013 -ffffffff802c01f4,00000013 -ffffffff802c030c,00000013 -ffffffff802c0460,00000013 -ffffffff802c04ac,00000013 -ffffffff802c0648,00000013 -ffffffff802c06c4,00000013 -ffffffff802c10c0,00000013 -ffffffff802c11d8,00000013 -ffffffff802c13a8,00000013 -ffffffff802c14e8,00000013 -ffffffff802c1544,00000013 -ffffffff802c2030,00000013 -ffffffff802c20f8,00000013 -ffffffff802c2940,00000013 -ffffffff802c2b7c,00000013 -ffffffff802c2cd8,00000013 -ffffffff802c30c0,00000013 -ffffffff802c3388,00000013 -ffffffff802c3424,00000013 -ffffffff802c38ac,00000013 -ffffffff802c3a30,00000013 -ffffffff802c3a80,00000013 -ffffffff802c3bcc,00000013 -ffffffff802c3c20,00000013 -ffffffff802c3d34,00000013 -ffffffff802c3d8c,00000013 -ffffffff802c3dc0,00000013 -ffffffff802c3fe8,00000013 -ffffffff802c40f0,00000013 -ffffffff802c418c,00000013 -ffffffff802c4568,00000013 -ffffffff802c4dd0,00000013 -ffffffff802c4e9c,00000013 -ffffffff802c4fb8,00000013 -ffffffff802c505c,00000013 -ffffffff802c7c4c,00000013 -ffffffff802c7d2c,00000013 -ffffffff802c7dfc,00000013 -ffffffff802c7ec0,00000013 -ffffffff802c7f98,00000013 -ffffffff802c8058,00000013 -ffffffff802c8140,00000013 -ffffffff802c81b8,00000013 -ffffffff802c8284,00000013 -ffffffff802c84b8,00000013 -ffffffff802c85ec,00000013 -ffffffff802c8670,00000013 -ffffffff802c8788,00000013 -ffffffff802c87dc,00000013 -ffffffff802c8a04,00000013 -ffffffff802c8c68,00000013 -ffffffff802c91bc,00000013 -ffffffff802c91f8,00000013 -ffffffff802c92e0,00000013 -ffffffff802c9890,00000013 -ffffffff802c99d8,00000013 -ffffffff802c9ea0,00000013 -ffffffff802c9fcc,00000013 -ffffffff802ca184,00000013 -ffffffff802ca2e4,00000013 -ffffffff802ca358,00000013 -ffffffff802cab58,00000013 -ffffffff802cb28c,00000013 -ffffffff802cb3f4,00000013 -ffffffff802cb49c,00000013 -ffffffff802cb5fc,00000013 -ffffffff802d1280,00000013 -ffffffff802d14dc,00000013 -ffffffff802d153c,00000013 -ffffffff802d16f8,00000013 -ffffffff802d331c,00000013 -ffffffff802d3400,00000013 -ffffffff802d34e4,00000013 -ffffffff802d3538,00000013 -ffffffff802d48cc,00000013 -ffffffff802d4a14,00000013 -ffffffff802d4f70,00000013 -ffffffff802d4fa8,00000013 -ffffffff802d5bbc,00000013 -ffffffff802d5bf4,00000013 -ffffffff802d5c80,00000013 -ffffffff802d5cc8,00000013 -ffffffff802d6118,00000013 -ffffffff802d9fe0,00000013 -ffffffff802de450,00000013 -ffffffff802dea94,00000013 -ffffffff802df6a8,00000013 -ffffffff802dfa50,00000013 -ffffffff802e07dc,00000013 -ffffffff802e0eb0,00000013 -ffffffff802e14f8,00000013 -ffffffff802e1558,00000013 -ffffffff802e15c4,00000013 -ffffffff802e16f4,00000013 -ffffffff802e17a8,00000013 -ffffffff802e1940,00000013 -ffffffff802e3714,00000013 -ffffffff802e4020,00000013 -ffffffff802e425c,00000013 -ffffffff802e4294,00000013 -ffffffff802e43ec,00000013 -ffffffff802e4424,00000013 -ffffffff802e465c,00000013 -ffffffff802e4e28,00000013 -ffffffff802e5020,00000013 -ffffffff802e53fc,00000013 -ffffffff802e55e8,00000013 -ffffffff802e5a38,00000013 -ffffffff802e5e18,00000013 -ffffffff802e5f88,00000013 -ffffffff802e66bc,00000013 -ffffffff802e8f0c,00000013 -ffffffff802ea6f0,00000013 -ffffffff802ea804,00000013 -ffffffff802eaee4,00000013 -ffffffff802eafe8,00000013 -ffffffff802eb0d0,00000013 -ffffffff802ee158,00000013 -ffffffff802ee200,00000013 -ffffffff802ee328,00000013 -ffffffff802ee414,00000013 -ffffffff802ee518,00000013 -ffffffff802ee618,00000013 -ffffffff802ee74c,00000013 -ffffffff802ee830,00000013 -ffffffff802ee98c,00000013 -ffffffff802eeb70,00000013 -ffffffff802eec7c,00000013 -ffffffff802eeebc,00000013 -ffffffff802ef3d4,00000013 -ffffffff802ef53c,00000013 -ffffffff802ef5f8,00000013 -ffffffff802ef864,00000013 -ffffffff802ef958,00000013 -ffffffff802efa58,00000013 -ffffffff802efb00,00000013 -ffffffff802efb68,00000013 -ffffffff802efe5c,00000013 -ffffffff802eff68,00000013 -ffffffff802f0044,00000013 -ffffffff802f025c,00000013 -ffffffff802f0394,00000013 -ffffffff802f0400,00000013 -ffffffff802f0468,00000013 -ffffffff802f0944,00000013 -ffffffff802f3124,00000013 -ffffffff802f3754,00000013 -ffffffff802f388c,00000013 -ffffffff802f3e28,00000013 -ffffffff802f3ee4,00000013 -ffffffff802f5524,00000013 -ffffffff802f567c,00000013 -ffffffff802f6be8,00000013 -ffffffff802f6dd4,00000013 -ffffffff802f6f48,00000013 -ffffffff802f7a14,00000013 -ffffffff802f8814,00000013 -ffffffff802f9904,00000013 -ffffffff802fa4d4,00000013 -ffffffff802ff028,00000013 -ffffffff802ff5e4,00000013 -ffffffff802fff7c,00000013 -ffffffff8030136c,00000013 -ffffffff803023f8,00000013 -ffffffff80302bd0,00000013 -ffffffff80304a8c,00000013 -ffffffff80304b84,00000013 -ffffffff80304c0c,00000013 -ffffffff80304c94,00000013 -ffffffff80305880,00000013 -ffffffff803058d4,00000013 -ffffffff803059a0,00000013 -ffffffff80305ab0,00000013 -ffffffff80307a58,00000013 -ffffffff80308118,00000013 -ffffffff803101f8,00000013 -ffffffff803104e4,00000013 -ffffffff803108a8,00000013 -ffffffff80310948,00000013 -ffffffff803109e8,00000013 -ffffffff80311ee0,00000013 -ffffffff80315118,00000013 -ffffffff80315988,00000013 -ffffffff80315be8,00000013 -ffffffff80315c98,00000013 -ffffffff80315e28,00000013 -ffffffff803161c8,00000013 -ffffffff803162d8,00000013 -ffffffff803165e4,00000013 -ffffffff803167a8,00000013 -ffffffff80316c40,00000013 -ffffffff803171a4,00000013 -ffffffff80317ddc,00000013 -ffffffff8031cd20,00000013 -ffffffff8031e26c,00000013 -ffffffff8031e300,00000013 -ffffffff8031f0e8,00000013 -ffffffff8031f160,00000013 -ffffffff8031f238,00000013 -ffffffff8031f390,00000013 -ffffffff8031f724,00000013 -ffffffff803210cc,00000013 -ffffffff803215d0,00000013 -ffffffff8032ae64,00000013 -ffffffff8032b2a4,00000013 -ffffffff8032b410,00000013 -ffffffff8032b5c0,00000013 -ffffffff8032b614,00000013 -ffffffff8032b764,00000013 -ffffffff8032b810,00000013 -ffffffff8032b8e4,00000013 -ffffffff8032b91c,00000013 -ffffffff8032bd3c,00000013 -ffffffff8032be54,00000013 -ffffffff8032bfbc,00000013 -ffffffff8032c014,00000013 -ffffffff8032c268,00000013 -ffffffff8032c550,00000013 -ffffffff8032c6e0,00000013 -ffffffff8032cbf8,00000013 -ffffffff8032cc8c,00000013 -ffffffff8032d49c,00000013 -ffffffff8032d8a8,00000013 -ffffffff8032da90,00000013 -ffffffff8032dfa8,00000013 -ffffffff8032e370,00000013 -ffffffff8032e7b4,00000013 -ffffffff8032e814,00000013 -ffffffff8032eb48,00000013 -ffffffff8032ecb4,00000013 -ffffffff8032ede4,00000013 -ffffffff8032effc,00000013 -ffffffff8032f3d4,00000013 -ffffffff8032f4a0,00000013 -ffffffff8032f810,00000013 -ffffffff8032f89c,00000013 -ffffffff8032f9d4,00000013 -ffffffff8032fa70,00000013 -ffffffff8032fafc,00000013 -ffffffff8032fd38,00000013 -ffffffff8032fdbc,00000013 -ffffffff8032fdfc,00000013 -ffffffff8032fedc,00000013 -ffffffff8033014c,00000013 -ffffffff80330198,00000013 -ffffffff803302b8,00000013 -ffffffff803303e4,00000013 -ffffffff80330494,00000013 -ffffffff80330564,00000013 -ffffffff80330618,00000013 -ffffffff80330674,00000013 -ffffffff803306e8,00000013 -ffffffff80330984,00000013 -ffffffff80330e88,00000013 -ffffffff803316e8,00000013 -ffffffff80331868,00000013 -ffffffff80331a60,00000013 -ffffffff803329b8,00000013 -ffffffff80332ca4,00000013 -ffffffff80332d64,00000013 -ffffffff80332f10,00000013 -ffffffff803333f4,00000013 -ffffffff80333544,00000013 -ffffffff803335f0,00000013 -ffffffff803336f0,00000013 -ffffffff80334128,00000013 -ffffffff803346bc,00000013 -ffffffff8033475c,00000013 -ffffffff80334868,00000013 -ffffffff80334f88,00000013 -ffffffff80352ad0,00000013 -ffffffff80352fcc,00000013 -ffffffff80356804,00000013 -ffffffff80356a44,00000013 -ffffffff80357f24,00000013 -ffffffff80360398,00000013 -ffffffff803604bc,00000013 -ffffffff8036070c,00000013 -ffffffff803616d8,00000013 -ffffffff803618cc,00000013 -ffffffff80361a14,00000013 -ffffffff80361b5c,00000013 -ffffffff80364748,00000013 -ffffffff80364b8c,00000013 -ffffffff80364c34,00000013 -ffffffff80364c88,00000013 -ffffffff80365014,00000013 -ffffffff80365148,00000013 -ffffffff80365320,00000013 -ffffffff80365430,00000013 -ffffffff80365a04,00000013 -ffffffff8036764c,00000013 -ffffffff80367720,00000013 -ffffffff80367980,00000013 -ffffffff80367ba8,00000013 -ffffffff80367cac,00000013 -ffffffff8036837c,00000013 -ffffffff8036b21c,00000013 -ffffffff8036b404,00000013 -ffffffff8036b6e0,00000013 -ffffffff8036b95c,00000013 -ffffffff8036baa4,00000013 -ffffffff8036bbe4,00000013 -ffffffff8036c958,00000013 -ffffffff8036c9dc,00000013 -ffffffff8036ca78,00000013 -ffffffff8036caf0,00000013 -ffffffff8036cc74,00000013 -ffffffff8036cd10,00000013 -ffffffff8036cdbc,00000013 -ffffffff8036ce40,00000013 -ffffffff8036d73c,00000013 -ffffffff8036e5ec,00000013 -ffffffff8036eedc,00000013 -ffffffff8036ef70,00000013 -ffffffff8036f010,00000013 -ffffffff8036f2ac,00000013 -ffffffff8036f35c,00000013 -ffffffff8036f410,00000013 -ffffffff8036f4b8,00000013 -ffffffff8036f574,00000013 -ffffffff8036f77c,00000013 -ffffffff8036f7f4,00000013 -ffffffff8036f924,00000013 -ffffffff8036f9d0,00000013 -ffffffff8036fab0,00000013 -ffffffff8036fbc4,00000013 -ffffffff8036fc10,00000013 -ffffffff8036fc88,00000013 -ffffffff8036fef4,00000013 -ffffffff8036ffd0,00000013 -ffffffff8037004c,00000013 -ffffffff803701bc,00000013 -ffffffff803701f4,00000013 -ffffffff803702dc,00000013 -ffffffff80370314,00000013 -ffffffff803703a8,00000013 -ffffffff803703dc,00000013 -ffffffff80370634,00000013 -ffffffff80370668,00000013 -ffffffff803706e8,00000013 -ffffffff803707f4,00000013 -ffffffff80370828,00000013 -ffffffff8037094c,00000013 -ffffffff803709f8,00000013 -ffffffff80370f9c,00000013 -ffffffff80371020,00000013 -ffffffff80371310,00000013 -ffffffff80371384,00000013 -ffffffff80371908,00000013 -ffffffff80371a10,00000013 -ffffffff80371ed0,00000013 -ffffffff80371fac,00000013 -ffffffff80372030,00000013 -ffffffff80372094,00000013 -ffffffff80373b00,00000013 -ffffffff80373dd4,00000013 -ffffffff80373e9c,00000013 -ffffffff80373f3c,00000013 -ffffffff80373ff8,00000013 -ffffffff80374158,00000013 -ffffffff80374274,00000013 -ffffffff803744c0,00000013 -ffffffff803745a8,00000013 -ffffffff803746ac,00000013 -ffffffff803746fc,00000013 -ffffffff803749f4,00000013 -ffffffff80374ac8,00000013 -ffffffff80374b1c,00000013 -ffffffff80374f50,00000013 -ffffffff8037965c,00000013 -ffffffff803797a8,00000013 -ffffffff80379834,00000013 -ffffffff803799dc,00000013 -ffffffff80379a8c,00000013 -ffffffff8037a064,00000013 -ffffffff8037a0f4,00000013 -ffffffff8037a3f0,00000013 -ffffffff8037b624,00000013 -ffffffff8037b674,00000013 -ffffffff8037b7f8,00000013 -ffffffff8037e078,00000013 -ffffffff8037eb18,00000013 -ffffffff8037eb6c,00000013 -ffffffff8037ec48,00000013 -ffffffff8037ecbc,00000013 -ffffffff8037ef5c,00000013 -ffffffff8037f084,00000013 -ffffffff8037f118,00000013 -ffffffff8037f2a4,00000013 -ffffffff8037f48c,00000013 -ffffffff803839bc,00000013 -ffffffff80383ba4,00000013 -ffffffff80387090,00000013 -ffffffff80387138,00000013 -ffffffff80387b04,00000013 -ffffffff80387c84,00000013 -ffffffff80387e78,00000013 -ffffffff80387f10,00000013 -ffffffff80388370,00000013 -ffffffff80389014,00000013 -ffffffff80391eb8,00000013 -ffffffff80391f40,00000013 -ffffffff80392020,00000013 -ffffffff80392788,00000013 -ffffffff80392898,00000013 -ffffffff80392ce4,00000013 -ffffffff80392ee4,00000013 -ffffffff80392f90,00000013 -ffffffff8039302c,00000013 -ffffffff80393988,00000013 -ffffffff803947d8,00000013 -ffffffff8039487c,00000013 -ffffffff80395b24,00000013 -ffffffff80395c14,00000013 -ffffffff80395c80,00000013 -ffffffff80395dcc,00000013 -ffffffff80395e94,00000013 -ffffffff80395fdc,00000013 -ffffffff803965fc,00000013 -ffffffff80396748,00000013 -ffffffff8039677c,00000013 -ffffffff80397050,00000013 -ffffffff8039714c,00000013 -ffffffff803971a8,00000013 -ffffffff803979bc,00000013 -ffffffff80397b1c,00000013 -ffffffff80397d7c,00000013 -ffffffff80397fdc,00000013 -ffffffff803980e0,00000013 -ffffffff803981d0,00000013 -ffffffff8039822c,00000013 -ffffffff8039831c,00000013 -ffffffff80398408,00000013 -ffffffff80398598,00000013 -ffffffff803985f4,00000013 -ffffffff803987b4,00000013 -ffffffff80398820,00000013 -ffffffff80398920,00000013 -ffffffff80398ee8,00000013 -ffffffff803992dc,00000013 -ffffffff8039a744,00000013 -ffffffff8039a8a8,00000013 -ffffffff8039a8e4,00000013 -ffffffff8039c154,00000013 -ffffffff8039c270,00000013 -ffffffff8039c310,00000013 -ffffffff8039c3e0,00000013 -ffffffff8039c548,00000013 -ffffffff8039c5f8,00000013 -ffffffff8039c6cc,00000013 -ffffffff8039c820,00000013 -ffffffff8039c8e4,00000013 -ffffffff8039c9fc,00000013 -ffffffff8039cdfc,00000013 -ffffffff8039d09c,00000013 -ffffffff8039d12c,00000013 -ffffffff8039d1b4,00000013 -ffffffff8039d2b0,00000013 -ffffffff8039d4d4,00000013 -ffffffff8039d5a0,00000013 -ffffffff8039d618,00000013 -ffffffff8039d918,00000013 -ffffffff8039dab4,00000013 -ffffffff8039de40,00000013 -ffffffff8039df64,00000013 -ffffffff8039e578,00000013 -ffffffff8039e650,00000013 -ffffffff8039e6ec,00000013 -ffffffff8039e820,00000013 -ffffffff8039eaac,00000013 -ffffffff803a1168,00000013 -ffffffff803a13cc,00000013 -ffffffff803a14e0,00000013 -ffffffff803a1628,00000013 -ffffffff803a172c,00000013 -ffffffff803a17a8,00000013 -ffffffff803a18c4,00000013 -ffffffff803a19a8,00000013 -ffffffff803a1bb4,00000013 -ffffffff803a1c44,00000013 -ffffffff803a1f80,00000013 -ffffffff803a208c,00000013 -ffffffff803a20f0,00000013 -ffffffff803a22ac,00000013 -ffffffff803a47d8,00000013 -ffffffff803a5644,00000013 -ffffffff803a56b0,00000013 -ffffffff803a57c0,00000013 -ffffffff803a5894,00000013 -ffffffff803a58f0,00000013 -ffffffff803a59cc,00000013 -ffffffff803a5a94,00000013 -ffffffff803a5f70,00000013 -ffffffff803a601c,00000013 -ffffffff803a60b8,00000013 -ffffffff803a63f8,00000013 -ffffffff803a7178,00000013 -ffffffff803a7258,00000013 -ffffffff803a7368,00000013 -ffffffff803a74d0,00000013 -ffffffff803a798c,00000013 -ffffffff803a7b44,00000013 -ffffffff803a91ec,00000013 -ffffffff803a942c,00000013 -ffffffff803a981c,00000013 -ffffffff803a98c4,00000013 -ffffffff803a9934,00000013 -ffffffff803a99d4,00000013 -ffffffff803a9a24,00000013 -ffffffff803a9a64,00000013 -ffffffff803baaac,00000013 -ffffffff803bfce8,00000013 -ffffffff803bfd80,00000013 -ffffffff803bfe50,00000013 -ffffffff803bff20,00000013 -ffffffff803bfffc,00000013 -ffffffff803c04c4,00000013 -ffffffff803c07f0,00000013 -ffffffff803c08bc,00000013 -ffffffff803c0994,00000013 -ffffffff803c0ae4,00000013 -ffffffff803c0ca4,00000013 -ffffffff803c0e94,00000013 -ffffffff803c11b4,00000013 -ffffffff803c1310,00000013 -ffffffff803c13e0,00000013 -ffffffff803c14ac,00000013 -ffffffff803c1634,00000013 -ffffffff803c166c,00000013 -ffffffff803c1a60,00000013 -ffffffff803c1b38,00000013 -ffffffff803c2060,00000013 -ffffffff803c20bc,00000013 -ffffffff803c2248,00000013 -ffffffff803c23c0,00000013 -ffffffff803c24e0,00000013 -ffffffff803c27c8,00000013 -ffffffff803c2954,00000013 -ffffffff803c2a34,00000013 -ffffffff803c2b0c,00000013 -ffffffff803c2bd4,00000013 -ffffffff803c2d00,00000013 -ffffffff803c3070,00000013 -ffffffff803c326c,00000013 -ffffffff803c32f0,00000013 -ffffffff803c35e8,00000013 -ffffffff803c3744,00000013 -ffffffff803c3804,00000013 -ffffffff803c3fcc,00000013 -ffffffff803c4160,00000013 -ffffffff803c43bc,00000013 -ffffffff803c45dc,00000013 -ffffffff803c4a40,00000013 -ffffffff803c4b2c,00000013 -ffffffff803c4c58,00000013 -ffffffff803c4cd4,00000013 -ffffffff803c507c,00000013 -ffffffff803c65bc,00000013 -ffffffff803c6c40,00000013 -ffffffff803c73c8,00000013 -ffffffff803c7580,00000013 -ffffffff803c7678,00000013 -ffffffff803c7a04,00000013 -ffffffff803c7a60,00000013 -ffffffff803c7ae0,00000013 -ffffffff803c7bcc,00000013 -ffffffff803c7cb0,00000013 -ffffffff803c7dd0,00000013 -ffffffff803c7e28,00000013 -ffffffff803c7e6c,00000013 -ffffffff803c7fc4,00000013 -ffffffff803c8160,00000013 -ffffffff803c822c,00000013 -ffffffff803c86e8,00000013 -ffffffff803c8a20,00000013 -ffffffff803c9db0,00000013 -ffffffff803ca69c,00000013 -ffffffff803caab0,00000013 -ffffffff803d5044,00000013 -ffffffff803dc460,00000013 -ffffffff803dc49c,00000013 -ffffffff803dc4e4,00000013 -ffffffff803dc7bc,00000013 -ffffffff803dc7fc,00000013 -ffffffff803dca98,00000013 -ffffffff803dcbc0,00000013 -ffffffff803dcc68,00000013 -ffffffff803dce44,00000013 -ffffffff803dcf50,00000013 -ffffffff803dcfc0,00000013 -ffffffff803dd1c0,00000013 -ffffffff803dd2b4,00000013 -ffffffff803dd314,00000013 -ffffffff803dd378,00000013 -ffffffff803dd430,00000013 -ffffffff803dd48c,00000013 -ffffffff803dd50c,00000013 -ffffffff803dd570,00000013 -ffffffff803dd5c8,00000013 -ffffffff803dd640,00000013 -ffffffff803dda30,00000013 -ffffffff803ddbe0,00000013 -ffffffff803ddcac,00000013 -ffffffff803ddec8,00000013 -ffffffff803de04c,00000013 -ffffffff803de12c,00000013 -ffffffff803de354,00000013 -ffffffff803de38c,00000013 -ffffffff803de458,00000013 -ffffffff803de4a4,00000013 -ffffffff803de5c4,00000013 -ffffffff803de5fc,00000013 -ffffffff803de694,00000013 -ffffffff803de7f8,00000013 -ffffffff803de8ac,00000013 -ffffffff803de900,00000013 -ffffffff803debb0,00000013 -ffffffff803dec40,00000013 -ffffffff803dec8c,00000013 -ffffffff803dede0,00000013 -ffffffff803df89c,00000013 -ffffffff803df91c,00000013 -ffffffff803dfbc8,00000013 -ffffffff803dfd94,00000013 -ffffffff803dff84,00000013 -ffffffff803e0738,00000013 -ffffffff803e0b74,00000013 -ffffffff803e0cf0,00000013 -ffffffff803e1020,00000013 -ffffffff803e10ac,00000013 -ffffffff803e1e50,00000013 -ffffffff803e1f50,00000013 -ffffffff803e2024,00000013 -ffffffff803e2288,00000013 -ffffffff803e2354,00000013 -ffffffff803e23e0,00000013 -ffffffff803e255c,00000013 -ffffffff803e25b4,00000013 -ffffffff803e2710,00000013 -ffffffff803e276c,00000013 -ffffffff803e2844,00000013 -ffffffff803e28a0,00000013 -ffffffff803e2b84,00000013 -ffffffff803e2bf8,00000013 -ffffffff803e2d84,00000013 -ffffffff803e2f4c,00000013 -ffffffff803e3128,00000013 -ffffffff803e329c,00000013 -ffffffff803e33c8,00000013 -ffffffff803e3674,00000013 -ffffffff803e36cc,00000013 -ffffffff803e3740,00000013 -ffffffff803e38ac,00000013 -ffffffff803e3950,00000013 -ffffffff803e3a60,00000013 -ffffffff803e3ae4,00000013 -ffffffff803e3eec,00000013 -ffffffff803e3f68,00000013 -ffffffff803e437c,00000013 -ffffffff803e6438,00000013 -ffffffff803e653c,00000013 -ffffffff803e79cc,00000013 -ffffffff803e7af4,00000013 -ffffffff803e80fc,00000013 -ffffffff803e8354,00000013 -ffffffff803e86cc,00000013 -ffffffff803e9bd4,00000013 -ffffffff803e9cfc,00000013 -ffffffff803e9f74,00000013 -ffffffff803ea4e0,00000013 -ffffffff803ea5ac,00000013 -ffffffff803ea664,00000013 -ffffffff803ea844,00000013 -ffffffff803ea96c,00000013 -ffffffff803eaa78,00000013 -ffffffff803eab7c,00000013 -ffffffff803eb31c,00000013 -ffffffff803eb3e8,00000013 -ffffffff803eb4b4,00000013 -ffffffff803eb9a0,00000013 -ffffffff803ebb04,00000013 -ffffffff803fa62c,00000013 -ffffffff803fa6e8,00000013 -ffffffff803fa7bc,00000013 -ffffffff803fa8f0,00000013 -ffffffff803faa1c,00000013 -ffffffff803faad0,00000013 -ffffffff803fad24,00000013 -ffffffff803fade4,00000013 -ffffffff803fb00c,00000013 -ffffffff803fb048,00000013 -ffffffff803fb0b8,00000013 -ffffffff803fb244,00000013 -ffffffff803fba5c,00000013 -ffffffff803fbbec,00000013 -ffffffff803fbcb8,00000013 -ffffffff803fbd3c,00000013 -ffffffff803fbf50,00000013 -ffffffff803fc048,00000013 -ffffffff803fc0a8,00000013 -ffffffff803fc2a4,00000013 -ffffffff803fc38c,00000013 -ffffffff803fc648,00000013 -ffffffff803fc70c,00000013 -ffffffff803fc7e4,00000013 -ffffffff803fc8ac,00000013 -ffffffff803fcaac,00000013 -ffffffff803fcbe4,00000013 -ffffffff803fce9c,00000013 -ffffffff803fd0f8,00000013 -ffffffff803fd1a4,00000013 -ffffffff803fd30c,00000013 -ffffffff803fd490,00000013 -ffffffff803fd5d0,00000013 -ffffffff803fd688,00000013 -ffffffff803fd728,00000013 -ffffffff803fdb30,00000013 -ffffffff803fdfe4,00000013 -ffffffff803fe078,00000013 -ffffffff803fe130,00000013 -ffffffff803fe3f4,00000013 -ffffffff803fe4f4,00000013 -ffffffff803fe5e8,00000013 -ffffffff803fe960,00000013 -ffffffff803fea04,00000013 -ffffffff803fea94,00000013 -ffffffff803feaf4,00000013 -ffffffff803febfc,00000013 -ffffffff803fec64,00000013 -ffffffff803fece4,00000013 -ffffffff803feff0,00000013 -ffffffff803ff134,00000013 -ffffffff803ff440,00000013 -ffffffff803ff4bc,00000013 -ffffffff803ff528,00000013 -ffffffff803ff668,00000013 -ffffffff803ff7b4,00000013 -ffffffff803ff818,00000013 -ffffffff803ff868,00000013 -ffffffff803ff9ac,00000013 -ffffffff803ffb38,00000013 -ffffffff803ffc7c,00000013 -ffffffff803ffd34,00000013 -ffffffff803ffe2c,00000013 -ffffffff80400450,00000013 -ffffffff804004dc,00000013 -ffffffff8040060c,00000013 -ffffffff80400678,00000013 -ffffffff80400840,00000013 -ffffffff804019ec,00000013 -ffffffff80401b8c,00000013 -ffffffff80401dec,00000013 -ffffffff804022b4,00000013 -ffffffff804023d4,00000013 -ffffffff80403488,00000013 -ffffffff804036f8,00000013 -ffffffff80403758,00000013 -ffffffff8040382c,00000013 -ffffffff804038a0,00000013 -ffffffff8040398c,00000013 -ffffffff804039fc,00000013 -ffffffff80403b40,00000013 -ffffffff80403c9c,00000013 -ffffffff80403d04,00000013 -ffffffff804043d8,00000013 -ffffffff804045c4,00000013 -ffffffff804046d0,00000013 -ffffffff804048a4,00000013 -ffffffff804049a8,00000013 -ffffffff80405f00,00000013 -ffffffff80406040,00000013 -ffffffff8040624c,00000013 -ffffffff80406374,00000013 -ffffffff80406430,00000013 -ffffffff8040651c,00000013 -ffffffff80406624,00000013 -ffffffff80406700,00000013 -ffffffff804067f0,00000013 -ffffffff8040698c,00000013 -ffffffff80406b6c,00000013 -ffffffff80406d28,00000013 -ffffffff80406f58,00000013 -ffffffff80407284,00000013 -ffffffff80408048,00000013 -ffffffff8040814c,00000013 -ffffffff8040aa4c,00000013 -ffffffff8040abb8,00000013 -ffffffff8040ac7c,00000013 -ffffffff8040af54,00000013 -ffffffff8040b0d0,00000013 -ffffffff8040b30c,00000013 -ffffffff8040ba98,00000013 -ffffffff8040bb68,00000013 -ffffffff8040bd00,00000013 -ffffffff8040bde4,00000013 -ffffffff8040bf60,00000013 -ffffffff8040c00c,00000013 -ffffffff8040c864,00000013 -ffffffff8040c9ec,00000013 -ffffffff8040d038,00000013 -ffffffff8040d758,00000013 -ffffffff8040e168,00000013 -ffffffff8040e1e0,00000013 -ffffffff8040e42c,00000013 -ffffffff8040ea2c,00000013 -ffffffff8040eb30,00000013 -ffffffff8040ebe0,00000013 -ffffffff8040edd4,00000013 -ffffffff8040f44c,00000013 -ffffffff8040f510,00000013 -ffffffff8040f5a0,00000013 -ffffffff8040ffc4,00000013 -ffffffff804100a8,00000013 -ffffffff80412d20,00000013 -ffffffff80412de4,00000013 -ffffffff80412f30,00000013 -ffffffff80413010,00000013 -ffffffff804130b4,00000013 -ffffffff80413128,00000013 -ffffffff804131ec,00000013 -ffffffff80413264,00000013 -ffffffff80413398,00000013 -ffffffff804133f0,00000013 -ffffffff80413508,00000013 -ffffffff804135d0,00000013 -ffffffff80413648,00000013 -ffffffff804136b4,00000013 -ffffffff80413754,00000013 -ffffffff80413908,00000013 -ffffffff80413978,00000013 -ffffffff80413a7c,00000013 -ffffffff80413aec,00000013 -ffffffff80413b78,00000013 -ffffffff80413c04,00000013 -ffffffff80413cf0,00000013 -ffffffff80413dcc,00000013 -ffffffff80413ea8,00000013 -ffffffff8041406c,00000013 -ffffffff80414154,00000013 -ffffffff804142a8,00000013 -ffffffff80414330,00000013 -ffffffff804143b4,00000013 -ffffffff80414430,00000013 -ffffffff8041447c,00000013 -ffffffff804144c4,00000013 -ffffffff804147ac,00000013 -ffffffff8041484c,00000013 -ffffffff804149c0,00000013 -ffffffff80414a2c,00000013 -ffffffff80414aa8,00000013 -ffffffff80414c40,00000013 -ffffffff80414cd8,00000013 -ffffffff80414d4c,00000013 -ffffffff804162a4,00000013 -ffffffff804163c8,00000013 -ffffffff80416774,00000013 -ffffffff804167c4,00000013 -ffffffff8041711c,00000013 -ffffffff80417274,00000013 -ffffffff804172ec,00000013 -ffffffff8041742c,00000013 -ffffffff8041749c,00000013 -ffffffff80417568,00000013 -ffffffff8041b7cc,00000013 -ffffffff8041b928,00000013 -ffffffff8041b980,00000013 -ffffffff8041ba44,00000013 -ffffffff8041bab0,00000013 -ffffffff8041c430,00000013 -ffffffff8041c4ac,00000013 -ffffffff8041c628,00000013 -ffffffff8041c728,00000013 -ffffffff8041c7f4,00000013 -ffffffff8041c93c,00000013 -ffffffff8041ce24,00000013 -ffffffff8041cef4,00000013 -ffffffff8041cf54,00000013 -ffffffff8041d400,00000013 -ffffffff8041d4b8,00000013 -ffffffff8041d524,00000013 -ffffffff8041d64c,00000013 -ffffffff8041d6e8,00000013 -ffffffff8041d720,00000013 -ffffffff8041d78c,00000013 -ffffffff8041d848,00000013 -ffffffff8041d884,00000013 -ffffffff8041da04,00000013 -ffffffff8041da9c,00000013 -ffffffff8041dad4,00000013 -ffffffff8041db68,00000013 -ffffffff8041dbec,00000013 -ffffffff8041dc40,00000013 -ffffffff8041dde8,00000013 -ffffffff8041df48,00000013 -ffffffff8041dfa4,00000013 -ffffffff8041dff8,00000013 -ffffffff8041e044,00000013 -ffffffff8041e14c,00000013 -ffffffff8041e898,00000013 -ffffffff8041ed84,00000013 -ffffffff8041edcc,00000013 -ffffffff8041ee9c,00000013 -ffffffff8041ef1c,00000013 -ffffffff8041ef54,00000013 -ffffffff8041f2cc,00000013 -ffffffff8041f304,00000013 -ffffffff8041f35c,00000013 -ffffffff8041f3c8,00000013 -ffffffff8041f438,00000013 -ffffffff8041f4ec,00000013 -ffffffff8041f5c0,00000013 -ffffffff8041f67c,00000013 -ffffffff8041f6d8,00000013 -ffffffff8041f754,00000013 -ffffffff8041f8a4,00000013 -ffffffff8041f9c8,00000013 -ffffffff8041fa88,00000013 -ffffffff8041fb00,00000013 -ffffffff8041fbbc,00000013 -ffffffff804207cc,00000013 -ffffffff804252ac,00000013 -ffffffff80425874,00000013 -ffffffff80426150,00000013 -ffffffff804262ac,00000013 -ffffffff80426390,00000013 -ffffffff8042646c,00000013 -ffffffff8042655c,00000013 -ffffffff80426738,00000013 -ffffffff8042699c,00000013 -ffffffff80426afc,00000013 -ffffffff8042c23c,00000013 -ffffffff8042c314,00000013 -ffffffff8042c490,00000013 -ffffffff8042ca70,00000013 -ffffffff8042d4cc,00000013 -ffffffff8042d694,00000013 -ffffffff8042d718,00000013 -ffffffff8042d7e8,00000013 -ffffffff8042db2c,00000013 -ffffffff8042dbdc,00000013 -ffffffff8042de20,00000013 -ffffffff8042decc,00000013 -ffffffff8042e22c,00000013 -ffffffff8042e480,00000013 -ffffffff8042e528,00000013 -ffffffff8042f124,00000013 -ffffffff8042f160,00000013 -ffffffff8042fcf0,00000013 -ffffffff8042ff84,00000013 -ffffffff80430078,00000013 -ffffffff8043010c,00000013 -ffffffff80430464,00000013 -ffffffff80430644,00000013 -ffffffff804306a4,00000013 -ffffffff8043073c,00000013 -ffffffff80430860,00000013 -ffffffff804308a8,00000013 -ffffffff80430a28,00000013 -ffffffff80430bb0,00000013 -ffffffff80430cc4,00000013 -ffffffff80430d78,00000013 -ffffffff80430e10,00000013 -ffffffff80430fd8,00000013 -ffffffff80431058,00000013 -ffffffff804310f4,00000013 -ffffffff80431210,00000013 -ffffffff80431274,00000013 -ffffffff804312a0,00000013 -ffffffff804312f0,00000013 -ffffffff80431380,00000013 -ffffffff8043143c,00000013 -ffffffff80431490,00000013 -ffffffff80431700,00000013 -ffffffff804317d8,00000013 -ffffffff80431908,00000013 -ffffffff804319a0,00000013 -ffffffff80431ac0,00000013 -ffffffff80431bf4,00000013 -ffffffff80431c8c,00000013 -ffffffff804325c8,00000013 -ffffffff804326c8,00000013 -ffffffff804327b0,00000013 -ffffffff8043286c,00000013 -ffffffff80432938,00000013 -ffffffff80432a8c,00000013 -ffffffff80433044,00000013 -ffffffff804330cc,00000013 -ffffffff80433118,00000013 -ffffffff8043318c,00000013 -ffffffff80433308,00000013 -ffffffff804333bc,00000013 -ffffffff804334ac,00000013 -ffffffff8043397c,00000013 -ffffffff80433c94,00000013 -ffffffff80433cdc,00000013 -ffffffff80433df0,00000013 -ffffffff80433ee4,00000013 -ffffffff804340c8,00000013 -ffffffff8043414c,00000013 -ffffffff80434244,00000013 -ffffffff804342c4,00000013 -ffffffff804344f4,00000013 -ffffffff80434540,00000013 -ffffffff804347cc,00000013 -ffffffff80434840,00000013 -ffffffff80434de8,00000013 -ffffffff80434e3c,00000013 -ffffffff80434edc,00000013 -ffffffff80435158,00000013 -ffffffff804351cc,00000013 -ffffffff80435224,00000013 -ffffffff8043528c,00000013 -ffffffff80435594,00000013 -ffffffff80435728,00000013 -ffffffff804357f4,00000013 -ffffffff80435840,00000013 -ffffffff804368f0,00000013 -ffffffff804369b0,00000013 -ffffffff80436ab4,00000013 -ffffffff80436c04,00000013 -ffffffff80436cf4,00000013 -ffffffff80436e54,00000013 -ffffffff80436eb8,00000013 -ffffffff80437208,00000013 -ffffffff80437678,00000013 -ffffffff804378b4,00000013 -ffffffff804379b8,00000013 -ffffffff80437a80,00000013 -ffffffff80437db8,00000013 -ffffffff80437fd4,00000013 -ffffffff804383dc,00000013 -ffffffff80438470,00000013 -ffffffff80438590,00000013 -ffffffff8043862c,00000013 -ffffffff80439278,00000013 -ffffffff80439414,00000013 -ffffffff80439a8c,00000013 -ffffffff80439b88,00000013 -ffffffff80439c94,00000013 -ffffffff80439d10,00000013 -ffffffff80439db0,00000013 -ffffffff8043a978,00000013 -ffffffff8043aaa8,00000013 -ffffffff8043ab80,00000013 -ffffffff8043abe8,00000013 -ffffffff8043ace0,00000013 -ffffffff8043b008,00000013 -ffffffff8044168c,00000013 -ffffffff80441700,00000013 -ffffffff80451d50,00000013 -ffffffff80452018,00000013 -ffffffff804523a4,00000013 -ffffffff8045247c,00000013 -ffffffff804525d8,00000013 -ffffffff80452d1c,00000013 -ffffffff80452e20,00000013 -ffffffff80452f70,00000013 -ffffffff804530a8,00000013 -ffffffff80453124,00000013 -ffffffff80453160,00000013 -ffffffff804534cc,00000013 -ffffffff804536a0,00000013 -ffffffff80453770,00000013 -ffffffff80455dc4,00000013 -ffffffff8046c704,00000013 -ffffffff8046c7bc,00000013 -ffffffff8046e054,00000013 -ffffffff804709c4,00000013 -ffffffff804742fc,00000013 -ffffffff8047e758,00000013 -ffffffff80482724,00000013 -ffffffff804827f4,00000013 -ffffffff80482958,00000013 -ffffffff804832c8,00000013 -ffffffff80484120,00000013 -ffffffff80496a28,00000013 -ffffffff80497708,00000013 -ffffffff8049792c,00000013 -ffffffff8049bad0,00000013 -ffffffff8049bb4c,00000013 -ffffffff8049c1b0,00000013 -ffffffff8049c2f4,00000013 -ffffffff8049cab8,00000013 -ffffffff8049caf4,00000013 -ffffffff8049cbac,00000013 -ffffffff8049cc00,00000013 -ffffffff8049e730,00000013 -ffffffff8049f160,00000013 -ffffffff8049fec0,00000013 -ffffffff804a1238,00000013 -ffffffff804a150c,00000013 -ffffffff804a163c,00000013 -ffffffff804a17f8,00000013 -ffffffff804a1ef4,00000013 -ffffffff804a2098,00000013 -ffffffff804a2280,00000013 -ffffffff804a789c,00000013 -ffffffff804a79f0,00000013 -ffffffff804a7f10,00000013 -ffffffff804a7ff0,00000013 -ffffffff804a91d4,00000013 -ffffffff804a9208,00000013 -ffffffff804a931c,00000013 -ffffffff804a9374,00000013 -ffffffff804a93c4,00000013 -ffffffff804a9408,00000013 -ffffffff804a9540,00000013 -ffffffff804a9598,00000013 -ffffffff804a969c,00000013 -ffffffff804a9764,00000013 -ffffffff804a9834,00000013 -ffffffff804a9874,00000013 -ffffffff804a991c,00000013 -ffffffff804a99c8,00000013 -ffffffff804b02a8,00000013 -ffffffff804b0668,00000013 -ffffffff804b073c,00000013 -ffffffff804b0b1c,00000013 -ffffffff804b0bfc,00000013 -ffffffff804b0d2c,00000013 -ffffffff804b0e84,00000013 -ffffffff804b0f38,00000013 -ffffffff804b1700,00000013 -ffffffff804b1770,00000013 -ffffffff804b18ac,00000013 -ffffffff804b194c,00000013 -ffffffff804b1ba8,00000013 -ffffffff804b1c28,00000013 -ffffffff804b25d4,00000013 -ffffffff804b27f0,00000013 -ffffffff804b298c,00000013 -ffffffff804b2be4,00000013 -ffffffff804b2f44,00000013 -ffffffff804b3058,00000013 -ffffffff804b3090,00000013 -ffffffff804b3178,00000013 -ffffffff804b31b0,00000013 -ffffffff804b3240,00000013 -ffffffff804b3274,00000013 -ffffffff804b3474,00000013 -ffffffff804b5ed0,00000013 -ffffffff804b868c,00000013 -ffffffff804b88cc,00000013 -ffffffff804bc4b0,00000013 -ffffffff804bc608,00000013 -ffffffff804bc784,00000013 -ffffffff804bc9bc,00000013 -ffffffff804bcc18,00000013 -ffffffff804bcce8,00000013 -ffffffff804bd8e8,00000013 -ffffffff804be11c,00000013 -ffffffff804be844,00000013 -ffffffff804c1734,00000013 -ffffffff804c1978,00000013 -ffffffff804c19dc,00000013 -ffffffff804c1aec,00000013 -ffffffff804c3314,00000013 -ffffffff804c34b8,00000013 -ffffffff804c35c0,00000013 -ffffffff804c3878,00000013 -ffffffff804c3940,00000013 -ffffffff804c39e4,00000013 -ffffffff804c3b14,00000013 -ffffffff804c3cac,00000013 -ffffffff804c3cf0,00000013 -ffffffff804c3f54,00000013 -ffffffff804c455c,00000013 -ffffffff804c4648,00000013 -ffffffff804c4904,00000013 -ffffffff804c4968,00000013 -ffffffff804c4aa0,00000013 -ffffffff804c4bc0,00000013 -ffffffff804c4c08,00000013 -ffffffff804c5000,00000013 -ffffffff804c503c,00000013 -ffffffff804c5094,00000013 -ffffffff804c5214,00000013 -ffffffff804c527c,00000013 -ffffffff804c5328,00000013 -ffffffff804c53b4,00000013 -ffffffff804c5434,00000013 -ffffffff804c7330,00000013 -ffffffff804c781c,00000013 -ffffffff804c7964,00000013 -ffffffff804c7b00,00000013 -ffffffff804c7c80,00000013 -ffffffff804c8ce0,00000013 -ffffffff804c927c,00000013 -ffffffff804c9364,00000013 -ffffffff804c93d4,00000013 -ffffffff804c9444,00000013 -ffffffff804c94b4,00000013 -ffffffff804c9524,00000013 -ffffffff804c9594,00000013 -ffffffff804c9604,00000013 -ffffffff804c9674,00000013 -ffffffff804c96e4,00000013 -ffffffff804c978c,00000013 -ffffffff804c9854,00000013 -ffffffff804c9924,00000013 -ffffffff804c9a48,00000013 -ffffffff804caac8,00000013 -ffffffff804cb1ac,00000013 -ffffffff804cb418,00000013 -ffffffff804cb484,00000013 -ffffffff804cb4f0,00000013 -ffffffff804cb55c,00000013 -ffffffff804cb650,00000013 -ffffffff804cb86c,00000013 -ffffffff804cbd78,00000013 -ffffffff804ccbf8,00000013 -ffffffff804ccddc,00000013 -ffffffff804ccf0c,00000013 -ffffffff804cd238,00000013 -ffffffff804cd2b8,00000013 -ffffffff804cd620,00000013 -ffffffff804cd70c,00000013 -ffffffff804cf944,00000013 -ffffffff804d1e38,00000013 -ffffffff804d1f30,00000013 -ffffffff804d325c,00000013 -ffffffff804d4660,00000013 -ffffffff804d49c8,00000013 -ffffffff804d4a30,00000013 -ffffffff804d4a98,00000013 -ffffffff804d4b00,00000013 -ffffffff804d5198,00000013 -ffffffff804d5238,00000013 -ffffffff804d5320,00000013 -ffffffff804d53e4,00000013 -ffffffff804d5460,00000013 -ffffffff804d7a08,00000013 -ffffffff804d93d0,00000013 -ffffffff804d94b0,00000013 -ffffffff804d95fc,00000013 -ffffffff804da2b4,00000013 -ffffffff804da7d4,00000013 -ffffffff804da8cc,00000013 -ffffffff804e2e50,00000013 -ffffffff804e347c,00000013 -ffffffff804e350c,00000013 -ffffffff804e41cc,00000013 -ffffffff804e4338,00000013 -ffffffff804e50c4,00000013 -ffffffff804e5138,00000013 -ffffffff804e5214,00000013 -ffffffff804e7090,00000013 -ffffffff804e7324,00000013 -ffffffff804e7b88,00000013 -ffffffff804e7f78,00000013 -ffffffff804e80f4,00000013 -ffffffff804e822c,00000013 -ffffffff804e83cc,00000013 -ffffffff804e84dc,00000013 -ffffffff804e85fc,00000013 -ffffffff804e878c,00000013 -ffffffff804e88b8,00000013 -ffffffff804e8b30,00000013 -ffffffff804e9750,00000013 -ffffffff804ea02c,00000013 -ffffffff804ea40c,00000013 -ffffffff804ec534,00000013 -ffffffff804ec634,00000013 -ffffffff804ec734,00000013 -ffffffff804ec9bc,00000013 -ffffffff804ed24c,00000013 -ffffffff804ed7a0,00000013 -ffffffff804eda90,00000013 -ffffffff804edb30,00000013 -ffffffff804edc50,00000013 -ffffffff804edd1c,00000013 -ffffffff804ede08,00000013 -ffffffff804ede5c,00000013 -ffffffff804edffc,00000013 -ffffffff804ee114,00000013 -ffffffff804ee2a8,00000013 -ffffffff804ee330,00000013 -ffffffff804ee548,00000013 -ffffffff804ee5cc,00000013 -ffffffff804ee63c,00000013 -ffffffff804ee6cc,00000013 -ffffffff804ee868,00000013 -ffffffff804ee8a0,00000013 -ffffffff804ee908,00000013 -ffffffff804ee990,00000013 -ffffffff804ee9ec,00000013 -ffffffff804eea9c,00000013 -ffffffff804eec10,00000013 -ffffffff804eec58,00000013 -ffffffff804eecb4,00000013 -ffffffff804eef28,00000013 -ffffffff804eefa4,00000013 -ffffffff804ef19c,00000013 -ffffffff804ef2e8,00000013 -ffffffff804ef684,00000013 -ffffffff804ef918,00000013 -ffffffff804f0368,00000013 -ffffffff804f0480,00000013 -ffffffff804f0510,00000013 -ffffffff804f0654,00000013 -ffffffff804f083c,00000013 -ffffffff804f3870,00000013 -ffffffff804f38dc,00000013 -ffffffff804f3968,00000013 -ffffffff804f39a4,00000013 -ffffffff804f39d4,00000013 -ffffffff804f3a54,00000013 -ffffffff804f3aa4,00000013 -ffffffff804f3b30,00000013 -ffffffff804f3b88,00000013 -ffffffff804f3c14,00000013 -ffffffff804fda88,00000013 -ffffffff804fdb6c,00000013 -ffffffff804ff044,00000013 -ffffffff804ffcdc,00000013 -ffffffff804ffd88,00000013 -ffffffff804ffe4c,00000013 -ffffffff80500bb0,00000013 -ffffffff80500eec,00000013 -ffffffff80501638,00000013 -ffffffff805110e0,00000013 -ffffffff805abd90,00000013 -ffffffff805abdd0,00000013 -ffffffff805abef8,00000013 -ffffffff805abff4,00000013 -ffffffff805b5cb0,00000013 -ffffffff805b5d8c,00000013 -ffffffff805b7ca0,00000013 -ffffffff805b7fa8,00000013 -ffffffff805d2f70,00000013 -ffffffff805d30a0,00000013 -ffffffff805d3ddc,00000013 -ffffffff805d3ef0,00000013 -ffffffff805d3ff0,00000013 -ffffffff805d40f0,00000013 -ffffffff805d41d0,00000013 -ffffffff805d4568,00000013 -ffffffff805d469c,00000013 -ffffffff805d47fc,00000013 -ffffffff805d4928,00000013 -ffffffff805db1f8,00000013 -ffffffff80635254,00000013 -ffffffff8063985c,00000013 -ffffffff806398e8,00000013 -ffffffff80639964,00000013 -ffffffff806399f8,00000013 -ffffffff8063cb90,00000013 -ffffffff8063cfc8,00000013 -ffffffff8063d064,00000013 -ffffffff8063d260,00000013 -ffffffff8063edc0,00000013 -ffffffff8063f1c0,00000013 -ffffffff8063f24c,00000013 -ffffffff8063f340,00000013 -ffffffff8064155c,00000013 -ffffffff806415f4,00000013 -ffffffff80641898,00000013 -ffffffff80641aec,00000013 -ffffffff80643a98,00000013 -ffffffff80645594,00000013 -ffffffff80646a38,00000013 -ffffffff80646bfc,00000013 -ffffffff80646e3c,00000013 -ffffffff80646f88,00000013 -ffffffff8064703c,00000013 -ffffffff80647138,00000013 -ffffffff80647218,00000013 -ffffffff8064c2ac,00000013 -ffffffff806531c8,00000013 -ffffffff8065371c,00000013 -ffffffff80659d64,00000013 -ffffffff80659e80,00000013 -ffffffff8065a36c,00000013 -ffffffff8065a488,00000013 -ffffffff8065a6bc,00000013 -ffffffff8065aa50,00000013 -ffffffff8065ab5c,00000013 -ffffffff8065ac70,00000013 -ffffffff8065b784,00000013 -ffffffff8065b9f8,00000013 -ffffffff8065bd60,00000013 -ffffffff8065c15c,00000013 -ffffffff8065c900,00000013 -ffffffff8065f2c4,00000013 -ffffffff8066191c,00000013 -ffffffff80663b30,00000013 -ffffffff8066452c,00000013 -ffffffff80664764,00000013 -ffffffff80664900,00000013 -ffffffff806649d4,00000013 -ffffffff80664b78,00000013 -ffffffff80664bb0,00000013 -ffffffff80664f3c,00000013 -ffffffff80665374,00000013 -ffffffff80665b1c,00000013 -ffffffff80665c90,00000013 -ffffffff8066604c,00000013 -ffffffff80667160,00000013 -ffffffff80668c10,00000013 -ffffffff8066be04,00000013 -ffffffff8066beb4,00000013 -ffffffff8066d7c0,00000013 -ffffffff80670be4,00000013 -ffffffff80677f74,00000013 -ffffffff80678b84,00000013 -ffffffff806798fc,00000013 -ffffffff80679bd8,00000013 -ffffffff80679c60,00000013 -ffffffff8067a928,00000013 -ffffffff8067b4f4,00000013 -ffffffff8067b5b0,00000013 -ffffffff8067c360,00000013 -ffffffff8067c410,00000013 -ffffffff8067c578,00000013 -ffffffff8067c840,00000013 -ffffffff8067e270,00000013 -ffffffff8067e348,00000013 -ffffffff8067e528,00000013 -ffffffff8067e59c,00000013 -ffffffff806814e4,00000013 -ffffffff80681db0,00000013 -ffffffff80681ff4,00000013 -ffffffff806820a8,00000013 -ffffffff80682188,00000013 -ffffffff80688218,00000013 -ffffffff80688338,00000013 -ffffffff80689e64,00000013 -ffffffff8068adac,00000013 -ffffffff8068d198,00000013 -ffffffff8068d1fc,00000013 -ffffffff8068d3d0,00000013 -ffffffff8068d4b4,00000013 -ffffffff8068d518,00000013 -ffffffff8068d660,00000013 -ffffffff8068d74c,00000013 -ffffffff8068d838,00000013 -ffffffff8068dad0,00000013 -ffffffff8068dc6c,00000013 -ffffffff8068dcbc,00000013 -ffffffff8068dd28,00000013 -ffffffff8068df0c,00000013 -ffffffff8068e194,00000013 -ffffffff8068e3ac,00000013 -ffffffff8068e65c,00000013 -ffffffff8068e6c0,00000013 -ffffffff8068e754,00000013 -ffffffff8068e8b0,00000013 -ffffffff8068e930,00000013 -ffffffff8068e9f4,00000013 -ffffffff8068eb00,00000013 -ffffffff8068ef34,00000013 -ffffffff8068ef84,00000013 -ffffffff8068f128,00000013 -ffffffff8068f1f0,00000013 -ffffffff806925a4,00000013 -ffffffff80692830,00000013 -ffffffff80694b84,00000013 -ffffffff80694c74,00000013 -ffffffff80694da4,00000013 -ffffffff80694e78,00000013 -ffffffff80694f68,00000013 -ffffffff8069508c,00000013 -ffffffff80695170,00000013 -ffffffff80695220,00000013 -ffffffff806952f0,00000013 -ffffffff806953a8,00000013 -ffffffff80695510,00000013 -ffffffff806955cc,00000013 -ffffffff806958e0,00000013 -ffffffff80696390,00000013 -ffffffff80696b40,00000013 -ffffffff806990a4,00000013 -ffffffff80699208,00000013 -ffffffff80699324,00000013 -ffffffff806993ec,00000013 -ffffffff8069960c,00000013 -ffffffff8069968c,00000013 -ffffffff8069d118,00000013 -ffffffff8069e394,00000013 -ffffffff8069fb2c,00000013 -ffffffff8069ffe4,00000013 -ffffffff806a03f8,00000013 -ffffffff806a04dc,00000013 -ffffffff806a0860,00000013 -ffffffff806a0f2c,00000013 -ffffffff806a32fc,00000013 -ffffffff806a3360,00000013 -ffffffff806a3fb8,00000013 -ffffffff806a7dc8,00000013 -ffffffff806abc18,00000013 -ffffffff806ac390,00000013 -ffffffff806adaf8,00000013 -ffffffff806ae034,00000013 -ffffffff806ae894,00000013 -ffffffff806ae964,00000013 -ffffffff806aea3c,00000013 -ffffffff806aeb04,00000013 -ffffffff806aebcc,00000013 -ffffffff806aec9c,00000013 -ffffffff806aed74,00000013 -ffffffff806af608,00000013 -ffffffff806af6c4,00000013 -ffffffff806b0218,00000013 -ffffffff806b0bb4,00000013 -ffffffff806b12a0,00000013 -ffffffff806b1368,00000013 -ffffffff806b1454,00000013 -ffffffff806b154c,00000013 -ffffffff806b16ec,00000013 -ffffffff806b176c,00000013 -ffffffff806b1a64,00000013 -ffffffff806b1b24,00000013 -ffffffff806b1bd0,00000013 -ffffffff806b1c5c,00000013 -ffffffff806b1cc0,00000013 -ffffffff806b1db0,00000013 -ffffffff806b2034,00000013 -ffffffff806b2310,00000013 -ffffffff806b237c,00000013 -ffffffff806b251c,00000013 -ffffffff806b2640,00000013 -ffffffff806b268c,00000013 -ffffffff806b2868,00000013 -ffffffff806b29a4,00000013 -ffffffff806b2b78,00000013 -ffffffff806b2e40,00000013 -ffffffff806b2f54,00000013 -ffffffff806b3074,00000013 -ffffffff806b31a8,00000013 -ffffffff806b3268,00000013 -ffffffff806b3318,00000013 -ffffffff806b33e4,00000013 -ffffffff806b34a8,00000013 -ffffffff806b3858,00000013 -ffffffff806b3bbc,00000013 -ffffffff806b3c64,00000013 -ffffffff806b3d08,00000013 -ffffffff806b3e70,00000013 -ffffffff806b3f34,00000013 -ffffffff806b40d8,00000013 -ffffffff806b4180,00000013 -ffffffff806b49e0,00000013 -ffffffff806b4c1c,00000013 -ffffffff806b53ec,00000013 -ffffffff806b5470,00000013 -ffffffff806b8864,00000013 -ffffffff806b88d4,00000013 -ffffffff806b8998,00000013 -ffffffff806b8a40,00000013 -ffffffff806b8c50,00000013 -ffffffff806b92c8,00000013 -ffffffff806ba43c,00000013 -ffffffff806ba548,00000013 -ffffffff806ba690,00000013 -ffffffff806ba774,00000013 -ffffffff806ba860,00000013 -ffffffff806ba97c,00000013 -ffffffff806ba9f8,00000013 -ffffffff806baa6c,00000013 -ffffffff806bac80,00000013 -ffffffff806bb354,00000013 -ffffffff806bb858,00000013 -ffffffff806be77c,00000013 -ffffffff806c3c10,00000013 -ffffffff806c3d54,00000013 -ffffffff806c3eb0,00000013 -ffffffff806c4054,00000013 -ffffffff806c437c,00000013 -ffffffff806cb4c4,00000013 -ffffffff806cb688,00000013 -ffffffff806cbea0,00000013 -ffffffff806cc2bc,00000013 -ffffffff806cc590,00000013 -ffffffff806cca9c,00000013 -ffffffff806cd8f0,00000013 -ffffffff806d2240,00000013 -ffffffff806d57bc,00000013 -ffffffff806dc710,00000013 -ffffffff806dc824,00000013 -ffffffff806dc938,00000013 -ffffffff806dee0c,00000013 -ffffffff806e4878,00000013 -ffffffff806e4a44,00000013 -ffffffff806e4b60,00000013 -ffffffff806e4c80,00000013 -ffffffff806e4dcc,00000013 -ffffffff806e4e6c,00000013 -ffffffff806e5dcc,00000013 -ffffffff806ed8f4,00000013 -ffffffff806edc38,00000013 -ffffffff806ede34,00000013 -ffffffff806edee4,00000013 -ffffffff806f1478,00000013 -ffffffff806f15b8,00000013 -ffffffff806f160c,00000013 -ffffffff806f1ec8,00000013 -ffffffff806f1ff4,00000013 -ffffffff806f20a0,00000013 -ffffffff807017d0,00000013 -ffffffff80701898,00000013 -ffffffff807148ac,00000013 -ffffffff8071493c,00000013 -ffffffff807149d0,00000013 -ffffffff80714e7c,00000013 -ffffffff8071c784,00000013 -ffffffff8071c998,00000013 -ffffffff8071cbb0,00000013 -ffffffff80722b88,00000013 -ffffffff80722c4c,00000013 -ffffffff80722d0c,00000013 -ffffffff80722e08,00000013 -ffffffff80722f00,00000013 -ffffffff80722ffc,00000013 -ffffffff80723c7c,00000013 -ffffffff80723ecc,00000013 -ffffffff80723fd0,00000013 -ffffffff80724118,00000013 -ffffffff80724210,00000013 -ffffffff80724304,00000013 -ffffffff80724aa4,00000013 -ffffffff80724c8c,00000013 -ffffffff80724d08,00000013 -ffffffff8072507c,00000013 -ffffffff807251a0,00000013 -ffffffff807252d8,00000013 -ffffffff80725318,00000013 -ffffffff807253d8,00000013 -ffffffff80726180,00000013 -ffffffff807261d4,00000013 -ffffffff8072635c,00000013 -ffffffff80726478,00000013 -ffffffff807264cc,00000013 -ffffffff80726b28,00000013 -ffffffff80726d88,00000013 -ffffffff80727928,00000013 -ffffffff80728250,00000013 -ffffffff80728588,00000013 -ffffffff80728750,00000013 -ffffffff8072881c,00000013 -ffffffff80728a14,00000013 -ffffffff80728b20,00000013 -ffffffff80728e34,00000013 -ffffffff8072b364,00000013 -ffffffff8072b404,00000013 -ffffffff8072b6e0,00000013 -ffffffff8072c978,00000013 -ffffffff8072ca68,00000013 -ffffffff8072cbac,00000013 -ffffffff8072cc80,00000013 -ffffffff8072cdcc,00000013 -ffffffff8072e284,00000013 -ffffffff8072e314,00000013 -ffffffff8072e658,00000013 -ffffffff8072ee94,00000013 -ffffffff80730f84,00000013 -ffffffff8073110c,00000013 -ffffffff807311b0,00000013 -ffffffff80731290,00000013 -ffffffff80731300,00000013 -ffffffff807314c4,00000013 -ffffffff80731584,00000013 -ffffffff80734fc4,00000013 -ffffffff807350bc,00000013 -ffffffff80736de0,00000013 -ffffffff8074d670,00000013 -ffffffff807510cc,00000013 -ffffffff80756d20,00000013 -ffffffff80756dfc,00000013 -ffffffff80756ec4,00000013 -ffffffff8075c88c,00000013 -ffffffff8075ca2c,00000013 -ffffffff8075cba0,00000013 -ffffffff8075d614,00000013 -ffffffff8075d794,00000013 -ffffffff80767128,00000013 -ffffffff80767258,00000013 -ffffffff807676a0,00000013 -ffffffff807676f4,00000013 -ffffffff8077be84,00000013 -ffffffff8077c3b8,00000013 -ffffffff8077d64c,00000013 -ffffffff8078c754,00000013 -ffffffff8078c880,00000013 -ffffffff8078c998,00000013 -ffffffff8078ca00,00000013 -ffffffff8078cfc0,00000013 -ffffffff8078d08c,00000013 -ffffffff8078d104,00000013 -ffffffff8078d3dc,00000013 -ffffffff8078d4b0,00000013 -ffffffff8078e5c4,00000013 -ffffffff8078f328,00000013 -ffffffff8078fedc,00000013 -ffffffff80790010,00000013 -ffffffff807900c8,00000013 -ffffffff8079271c,00000013 -ffffffff807927e8,00000013 -ffffffff807928cc,00000013 -ffffffff80792934,00000013 -ffffffff807955cc,00000013 -ffffffff80795a54,00000013 -ffffffff80795c4c,00000013 -ffffffff80795d50,00000013 -ffffffff80795e88,00000013 -ffffffff80795fb0,00000013 -ffffffff807960c4,00000013 -ffffffff807960f8,00000013 -ffffffff807962b0,00000013 -ffffffff80796428,00000013 -ffffffff8079656c,00000013 -ffffffff807966d0,00000013 -ffffffff80796908,00000013 -ffffffff80796a9c,00000013 -ffffffff80796e30,00000013 -ffffffff80796f14,00000013 -ffffffff80796ff8,00000013 -ffffffff807970b4,00000013 -ffffffff80797110,00000013 -ffffffff807971f4,00000013 -ffffffff8079722c,00000013 -ffffffff80797920,00000013 -ffffffff80797a00,00000013 -ffffffff80797a9c,00000013 -ffffffff80797f7c,00000013 -ffffffff80798028,00000013 -ffffffff8079a1e4,00000013 -ffffffff8079b674,00000013 -ffffffff8079b73c,00000013 -ffffffff8079b7c0,00000013 -ffffffff8079b840,00000013 -ffffffff8079b91c,00000013 -ffffffff8079b9b8,00000013 -ffffffff8079bb84,00000013 -ffffffff8079c138,00000013 -ffffffff8079cb5c,00000013 -ffffffff8079d1f8,00000013 -ffffffff8079d2e0,00000013 -ffffffff8079d3c0,00000013 -ffffffff8079d4a0,00000013 -ffffffff8079d574,00000013 -ffffffff8079d654,00000013 -ffffffff8079d758,00000013 -ffffffff8079d8ec,00000013 -ffffffff8079d998,00000013 -ffffffff8079dcf0,00000013 -ffffffff8079de80,00000013 -ffffffff8079e024,00000013 -ffffffff8079e1d0,00000013 -ffffffff8079e3f0,00000013 -ffffffff8079e44c,00000013 -ffffffff8079ed48,00000013 -ffffffff8079f000,00000013 -ffffffff8079fbfc,00000013 -ffffffff807a0e98,00000013 -ffffffff807a1b88,00000013 -ffffffff807a1f00,00000013 -ffffffff807a23c8,00000013 -ffffffff807c0828,00000013 -ffffffff807c0eb4,00000013 -ffffffff807c7ca8,00000013 -ffffffff807c7d44,00000013 -ffffffff807c7fb0,00000013 -ffffffff807c8804,00000013 -ffffffff807c8afc,00000013 -ffffffff807c8b80,00000013 -ffffffff807daffc,00000013 -ffffffff807dc404,00000013 -ffffffff807dc63c,00000013 -ffffffff807e7bdc,00000013 -ffffffff807e85ac,00000013 -ffffffff807e86f0,00000013 -ffffffff807e887c,00000013 -ffffffff807e904c,00000013 -ffffffff807e90d8,00000013 -ffffffff807e9248,00000013 -ffffffff807e932c,00000013 -ffffffff807ea0d0,00000013 -ffffffff807ea2dc,00000013 -ffffffff807ea390,00000013 -ffffffff807ea3dc,00000013 -ffffffff807ea438,00000013 -ffffffff807ea4ec,00000013 -ffffffff807ea528,00000013 -ffffffff807ea5d8,00000013 -ffffffff807ea634,00000013 -ffffffff807ecb2c,00000013 -ffffffff807ed260,00000013 -ffffffff807ed388,00000013 -ffffffff807ed948,00000013 -ffffffff807eed9c,00000013 -ffffffff807ef468,00000013 -ffffffff807ef994,00000013 -ffffffff807efc20,00000013 -ffffffff807f4f24,00000013 -ffffffff807f4ff0,00000013 -ffffffff807f52d8,00000013 -ffffffff807f5388,00000013 -ffffffff807f5544,00000013 -ffffffff807f55f4,00000013 -ffffffff807f7da4,00000013 -ffffffff807f800c,00000013 -ffffffff807fb188,00000013 -ffffffff80807278,00000013 -ffffffff80807340,00000013 -ffffffff8081ebb0,00000013 -ffffffff8081f4a4,00000013 -ffffffff80823978,00000013 -ffffffff80826618,00000013 -ffffffff808268c8,00000013 -ffffffff80826b4c,00000013 -ffffffff80826e84,00000013 -ffffffff808271b0,00000013 -ffffffff8082797c,00000013 -ffffffff808286e4,00000013 -ffffffff80836944,00000013 -ffffffff80836e34,00000013 -ffffffff808379b8,00000013 -ffffffff80837a90,00000013 -ffffffff80837ae8,00000013 -ffffffff80837e74,00000013 -ffffffff8083d14c,00000013 -ffffffff8083f42c,00000013 -ffffffff8083f73c,00000013 -ffffffff808420b0,00000013 -ffffffff808422b4,00000013 -ffffffff80842490,00000013 -ffffffff808425a4,00000013 -ffffffff80842734,00000013 -ffffffff80842918,00000013 -ffffffff80842b98,00000013 -ffffffff80842c98,00000013 -ffffffff80842d34,00000013 -ffffffff80842ecc,00000013 -ffffffff808430a0,00000013 -ffffffff80843170,00000013 -ffffffff808432b8,00000013 -ffffffff80843bc8,00000013 -ffffffff80843c6c,00000013 -ffffffff80843d54,00000013 -ffffffff8084a4a4,00000013 -ffffffff8084a61c,00000013 -ffffffff8084a710,00000013 -ffffffff8084b258,00000013 -ffffffff8084b39c,00000013 -ffffffff8084b4d8,00000013 -ffffffff8084b640,00000013 -ffffffff8084bd6c,00000013 -ffffffff8084d484,00000013 -ffffffff8084d554,00000013 -ffffffff80855ad0,00000013 -ffffffff8085d1cc,00000013 -ffffffff8086a984,00000013 -ffffffff8086b58c,00000013 -ffffffff8086b7cc,00000013 -ffffffff8086b87c,00000013 -ffffffff8086b98c,00000013 -ffffffff80875e54,00000013 -ffffffff808780e8,00000013 -ffffffff80878458,00000013 -ffffffff80878554,00000013 -ffffffff80880960,00000013 -ffffffff808818d0,00000013 -ffffffff8088190c,00000013 -ffffffff80881ba8,00000013 -ffffffff80881ca4,00000013 -ffffffff808820d0,00000013 -ffffffff808823ec,00000013 -ffffffff80882638,00000013 -ffffffff808829b8,00000013 -ffffffff808829f0,00000013 -ffffffff80882a8c,00000013 -ffffffff80882ac0,00000013 -ffffffff80882d24,00000013 -ffffffff80882e64,00000013 -ffffffff80883670,00000013 -ffffffff808836a4,00000013 -ffffffff80883da4,00000013 -ffffffff80883eb8,00000013 -ffffffff80883ef0,00000013 -ffffffff80884290,00000013 -ffffffff80884488,00000013 -ffffffff808844c0,00000013 -ffffffff8088453c,00000013 -ffffffff808855e0,00000013 -ffffffff80885734,00000013 -ffffffff80885a6c,00000013 -ffffffff80885bcc,00000013 -ffffffff80886324,00000013 -ffffffff808865ac,00000013 -ffffffff80886e9c,00000013 -ffffffff80887b6c,00000013 -ffffffff80888fac,00000013 -ffffffff8088cef0,00000013 -ffffffff808992b0,00000013 -ffffffff80899540,00000013 -ffffffff8089ee90,00000013 -ffffffff808a0414,00000013 -ffffffff808a0c8c,00000013 -ffffffff808a106c,00000013 -ffffffff808a1858,00000013 -ffffffff808a4034,00000013 -ffffffff808a4138,00000013 -ffffffff808a4508,00000013 -ffffffff808a483c,00000013 -ffffffff808a4b1c,00000013 -ffffffff808a5168,00000013 -ffffffff808a57ec,00000013 -ffffffff808a58c8,00000013 -ffffffff808a67d8,00000013 -ffffffff808a7bec,00000013 -ffffffff808a7fc4,00000013 -ffffffff808a8164,00000013 -ffffffff808a8494,00000013 -ffffffff808a8b08,00000013 -ffffffff808a9758,00000013 -ffffffff808aa564,00000013 -ffffffff808aa7c0,00000013 -ffffffff808aa840,00000013 -ffffffff808aba50,00000013 -ffffffff808abb04,00000013 -ffffffff808adcf0,00000013 -ffffffff808adf80,00000013 -ffffffff808ae068,00000013 -ffffffff808b1754,00000013 -ffffffff808b1904,00000013 -ffffffff808b1ac0,00000013 -ffffffff808b1d1c,00000013 -ffffffff808b1f08,00000013 -ffffffff808b1f94,00000013 -ffffffff808b1fe0,00000013 -ffffffff808b24f4,00000013 -ffffffff808b281c,00000013 -ffffffff808b286c,00000013 -ffffffff808b3860,00000013 -ffffffff808b38a8,00000013 -ffffffff808b3984,00000013 -ffffffff808b39d8,00000013 -ffffffff808b4dc4,00000013 -ffffffff808b4e2c,00000013 -ffffffff808b4f50,00000013 -ffffffff808b4f9c,00000013 -ffffffff808b65dc,00000013 -ffffffff808ba884,00000013 -ffffffff808bb428,00000013 -ffffffff808c535c,00000013 -ffffffff808d165c,00000013 -ffffffff808d17b8,00000013 -ffffffff808d19c4,00000013 -ffffffff808d1a30,00000013 -ffffffff808dbfe8,00000013 -ffffffff808df364,00000013 -ffffffff808df960,00000013 -ffffffff808e715c,00000013 -ffffffff808e7284,00000013 -ffffffff808e98a4,00000013 -ffffffff808e99a0,00000013 -ffffffff808e9a78,00000013 -ffffffff808ebeb4,00000013 -ffffffff808ed118,00000013 -ffffffff808ed830,00000013 -ffffffff808f3e40,00000013 -ffffffff808f3f80,00000013 -ffffffff808f4208,00000013 -ffffffff808f6840,00000013 -ffffffff808f6e84,00000013 -ffffffff808f7b40,00000013 -ffffffff808f7e44,00000013 -ffffffff808f7f0c,00000013 -ffffffff808f800c,00000013 -ffffffff808f80c8,00000013 -ffffffff808f81e8,00000013 -ffffffff808f8490,00000013 -ffffffff808f858c,00000013 -ffffffff808f8660,00000013 -ffffffff808f89a8,00000013 -ffffffff808f8b28,00000013 -ffffffff808f8bac,00000013 -ffffffff808f8d54,00000013 -ffffffff808f8d88,00000013 -ffffffff808f8ef4,00000013 -ffffffff808f8fb4,00000013 -ffffffff808f90ac,00000013 -ffffffff808f90f0,00000013 -ffffffff808f9138,00000013 -ffffffff808f9464,00000013 -ffffffff808f95d0,00000013 -ffffffff808f96e0,00000013 -ffffffff808f9c38,00000013 -ffffffff808f9c9c,00000013 -ffffffff808f9d34,00000013 -ffffffff808f9dac,00000013 -ffffffff808f9f20,00000013 -ffffffff808fa138,00000013 -ffffffff808fa258,00000013 -ffffffff808fa28c,00000013 -ffffffff808fa574,00000013 -ffffffff808fa928,00000013 -ffffffff808fa96c,00000013 -ffffffff808fa9c4,00000013 -ffffffff808fab00,00000013 -ffffffff808fab34,00000013 -ffffffff808faca8,00000013 -ffffffff808fad20,00000013 -ffffffff808faee8,00000013 -ffffffff808fb19c,00000013 -ffffffff808fb3e8,00000013 -ffffffff808fb4ac,00000013 -ffffffff808fb598,00000013 -ffffffff808fb5d0,00000013 -ffffffff808fb6d4,00000013 -ffffffff808fb708,00000013 -ffffffff808fb8d0,00000013 -ffffffff808fb9a4,00000013 -ffffffff808fba94,00000013 -ffffffff808fbb38,00000013 -ffffffff808fbd24,00000013 -ffffffff808fbedc,00000013 -ffffffff808fc18c,00000013 -ffffffff808fc1c0,00000013 -ffffffff808fc26c,00000013 -ffffffff808fc340,00000013 -ffffffff808fc378,00000013 -ffffffff808fc440,00000013 -ffffffff808fc494,00000013 -ffffffff808fc4cc,00000013 -ffffffff808fc520,00000013 -ffffffff808fc5d8,00000013 -ffffffff808fc6a0,00000013 -ffffffff808fc71c,00000013 -ffffffff808fc750,00000013 -ffffffff808fc790,00000013 -ffffffff808fcae8,00000013 -ffffffff808fcc20,00000013 -ffffffff808fcdd4,00000013 -ffffffff808fce40,00000013 -ffffffff808fceb0,00000013 -ffffffff808fcee8,00000013 -ffffffff808fcfb4,00000013 -ffffffff808fd2e0,00000013 -ffffffff808fd4dc,00000013 -ffffffff808fd5c4,00000013 -ffffffff808fd65c,00000013 -ffffffff808fd6e4,00000013 -ffffffff808fdb78,00000013 -ffffffff808fdeec,00000013 -ffffffff808fdf40,00000013 -ffffffff808fe3ec,00000013 -ffffffff808fe4d8,00000013 -ffffffff808fe6b0,00000013 -ffffffff808fe8a0,00000013 -ffffffff808fe984,00000013 -ffffffff80901234,00000013 -ffffffff80901780,00000013 -ffffffff80901b14,00000013 -ffffffff80901d98,00000013 -ffffffff80909da4,00000013 -ffffffff8090a0d8,00000013 -ffffffff8090cc38,00000013 -ffffffff8090db6c,00000013 -ffffffff8090e358,00000013 -ffffffff8090e540,00000013 -ffffffff8090e6e0,00000013 -ffffffff8090e798,00000013 -ffffffff8090e8d4,00000013 -ffffffff8090e924,00000013 -ffffffff8090f98c,00000013 -ffffffff8090fc14,00000013 -ffffffff8090fc88,00000013 -ffffffff8090fd0c,00000013 -ffffffff8090ff30,00000013 -ffffffff80910010,00000013 -ffffffff809100b8,00000013 -ffffffff80912620,00000013 -ffffffff8091309c,00000013 -ffffffff809131f4,00000013 -ffffffff809134ec,00000013 -ffffffff80915e7c,00000013 -ffffffff80919298,00000013 -ffffffff8091ed00,00000013 -ffffffff8091fdb0,00000013 -ffffffff8092d6d4,00000013 -ffffffff8092ded4,00000013 -ffffffff809344a8,00000013 -ffffffff80934510,00000013 -ffffffff809349ac,00000013 -ffffffff80936dfc,00000013 -ffffffff809374ec,00000013 -ffffffff80938394,00000013 -ffffffff8093cfe0,00000013 -ffffffff80941790,00000013 -ffffffff809418c0,00000013 -ffffffff80941948,00000013 -ffffffff8094898c,00000013 -ffffffff80948aec,00000013 -ffffffff8094bfd8,00000013 -ffffffff8094d08c,00000013 -ffffffff8094d1fc,00000013 -ffffffff8094d27c,00000013 -ffffffff8094d464,00000013 -ffffffff8094d9b8,00000013 -ffffffff8094da18,00000013 -ffffffff8094dc4c,00000013 -ffffffff8094dcbc,00000013 -ffffffff8094fb30,00000013 -ffffffff8094fbfc,00000013 -ffffffff8094fedc,00000013 -ffffffff80950334,00000013 -ffffffff80950504,00000013 -ffffffff8095079c,00000013 -ffffffff8095134c,00000013 -ffffffff8095160c,00000013 -ffffffff809519cc,00000013 -ffffffff80954204,00000013 -ffffffff80954654,00000013 -ffffffff80954708,00000013 -ffffffff80954b0c,00000013 -ffffffff80954d14,00000013 -ffffffff809555b8,00000013 -ffffffff80955684,00000013 -ffffffff80955734,00000013 -ffffffff80955a54,00000013 -ffffffff80955b2c,00000013 -ffffffff80955cdc,00000013 -ffffffff80956e70,00000013 -ffffffff80956f10,00000013 -ffffffff80956fe0,00000013 -ffffffff809570a4,00000013 -ffffffff80957164,00000013 -ffffffff80957274,00000013 -ffffffff80957354,00000013 -ffffffff80957408,00000013 -ffffffff80957518,00000013 -ffffffff809575f0,00000013 -ffffffff80957728,00000013 -ffffffff809577c4,00000013 -ffffffff80957960,00000013 -ffffffff809579e0,00000013 -ffffffff80957a48,00000013 -ffffffff80957bec,00000013 -ffffffff80957c48,00000013 -ffffffff80957e68,00000013 -ffffffff80957f0c,00000013 -ffffffff80957f5c,00000013 -ffffffff80958068,00000013 -ffffffff80958194,00000013 -ffffffff80958280,00000013 -ffffffff8095837c,00000013 -ffffffff8095856c,00000013 -ffffffff80958658,00000013 -ffffffff80958770,00000013 -ffffffff8095887c,00000013 -ffffffff8095899c,00000013 -ffffffff80958a74,00000013 -ffffffff80958ba8,00000013 -ffffffff80958c8c,00000013 -ffffffff80958d84,00000013 -ffffffff80958e08,00000013 -ffffffff80958f34,00000013 -ffffffff80959050,00000013 -ffffffff809591b0,00000013 -ffffffff80959378,00000013 -ffffffff8095940c,00000013 -ffffffff8095c0f0,00000013 -ffffffff8095c350,00000013 -ffffffff8095c9ac,00000013 -ffffffff8095ce20,00000013 -ffffffff8095db50,00000013 -ffffffff8095dbb8,00000013 -ffffffff8095dee4,00000013 -ffffffff8095df50,00000013 -ffffffff8095dfd0,00000013 -ffffffff8096e2e4,00000013 -ffffffff8096e3c4,00000013 -ffffffff8096e46c,00000013 -ffffffff8096e518,00000013 -ffffffff8096e5fc,00000013 -ffffffff8096e6a4,00000013 -ffffffff8096e80c,00000013 -ffffffff8096e914,00000013 -ffffffff8096e9d4,00000013 -ffffffff8096eab4,00000013 -ffffffff8096eb68,00000013 -ffffffff8096edac,00000013 -ffffffff8096ef48,00000013 -ffffffff8096f9dc,00000013 -ffffffff8096fae8,00000013 -ffffffff8096fb88,00000013 -ffffffff8096fc58,00000013 -ffffffff80970018,00000013 -ffffffff80970254,00000013 -ffffffff8097054c,00000013 -ffffffff80970580,00000013 -ffffffff80975230,00000013 -ffffffff80975418,00000013 -ffffffff809757e4,00000013 -ffffffff809758d8,00000013 -ffffffff80975960,00000013 -ffffffff809773b8,00000013 -ffffffff80977440,00000013 -ffffffff809775e0,00000013 -ffffffff809788c8,00000013 -ffffffff8097899c,00000013 -ffffffff80978a30,00000013 -ffffffff8097d5a8,00000013 -ffffffff8097d680,00000013 -ffffffff8097d79c,00000013 -ffffffff8097d8f8,00000013 -ffffffff8097dac4,00000013 -ffffffff8097dd7c,00000013 -ffffffff8097dee4,00000013 -ffffffff8097e100,00000013 -ffffffff8097e1f0,00000013 -ffffffff8097e2ac,00000013 -ffffffff8097e3bc,00000013 -ffffffff8097e470,00000013 -ffffffff8097e508,00000013 -ffffffff8097e5b8,00000013 -ffffffff8097e5ec,00000013 -ffffffff8097e930,00000013 -ffffffff8097ea60,00000013 -ffffffff8097eb10,00000013 -ffffffff8097ecb4,00000013 -ffffffff8097ee0c,00000013 -ffffffff8097f104,00000013 -ffffffff8097f1e4,00000013 -ffffffff8097f250,00000013 -ffffffff8097f2b4,00000013 -ffffffff8097f32c,00000013 -ffffffff8097f568,00000013 -ffffffff8097f858,00000013 -ffffffff8097f8d8,00000013 -ffffffff8097f960,00000013 -ffffffff8097fa7c,00000013 -ffffffff8097fb48,00000013 -ffffffff8097fbb4,00000013 -ffffffff8097fdd4,00000013 -ffffffff8097ff6c,00000013 -ffffffff8097ffa8,00000013 -ffffffff80980078,00000013 -ffffffff809800ac,00000013 -ffffffff80980428,00000013 -ffffffff8098178c,00000013 -ffffffff80981884,00000013 -ffffffff809819d0,00000013 -ffffffff80981eac,00000013 -ffffffff80982084,00000013 -ffffffff8098210c,00000013 -ffffffff80982208,00000013 -ffffffff809822a8,00000013 -ffffffff80982374,00000013 -ffffffff80982448,00000013 -ffffffff80984a70,00000013 -ffffffff80984c4c,00000013 -ffffffff80984d00,00000013 -ffffffff809850b0,00000013 -ffffffff80985110,00000013 -ffffffff80985484,00000013 -ffffffff80985854,00000013 -ffffffff809858f0,00000013 -ffffffff809860c0,00000013 -ffffffff809863cc,00000013 -ffffffff8098641c,00000013 -ffffffff809867b8,00000013 -ffffffff80986858,00000013 -ffffffff809870d8,00000013 -ffffffff809873d8,00000013 -ffffffff80987504,00000013 -ffffffff80987944,00000013 -ffffffff8098a07c,00000013 -ffffffff8098a210,00000013 -ffffffff8098a2f8,00000013 -ffffffff8098a5c8,00000013 -ffffffff8098a984,00000013 -ffffffff8098aa28,00000013 -ffffffff8098ab04,00000013 -ffffffff8098abf4,00000013 -ffffffff8098ac94,00000013 -ffffffff8098acfc,00000013 -ffffffff8098ae80,00000013 -ffffffff8098af28,00000013 -ffffffff8098afa4,00000013 -ffffffff8098b1c8,00000013 -ffffffff8098b340,00000013 -ffffffff8098b3f4,00000013 -ffffffff8098b528,00000013 -ffffffff8098b6d4,00000013 -ffffffff8098b9b4,00000013 -ffffffff8098ba6c,00000013 -ffffffff8098bd9c,00000013 -ffffffff8098be5c,00000013 -ffffffff8098c7f8,00000013 -ffffffff8099821c,00000013 -ffffffff809982b4,00000013 -ffffffff80998374,00000013 -ffffffff8099847c,00000013 -ffffffff809995c8,00000013 -ffffffff80999a64,00000013 -ffffffff8099e300,00000013 -ffffffff8099e3d8,00000013 -ffffffff8099e478,00000013 -ffffffff8099e544,00000013 -ffffffff8099e5ac,00000013 -ffffffff8099e6e8,00000013 -ffffffff8099e7ac,00000013 -ffffffff8099eb24,00000013 -ffffffff8099ece0,00000013 -ffffffff8099ef5c,00000013 -ffffffff8099efec,00000013 -ffffffff809a10fc,00000013 -ffffffff809a11b0,00000013 -ffffffff809a1260,00000013 -ffffffff809a16a4,00000013 -ffffffff809a23b4,00000013 -ffffffff809a25fc,00000013 -ffffffff809a26ac,00000013 -ffffffff809a271c,00000013 -ffffffff809a2924,00000013 -ffffffff809a58e0,00000013 -ffffffff809a59a4,00000013 -ffffffff809abc58,00000013 -ffffffff809abcf8,00000013 -ffffffff809abda0,00000013 -ffffffff809abe50,00000013 -ffffffff809abf68,00000013 -ffffffff809ac240,00000013 -ffffffff809ac37c,00000013 -ffffffff809ac740,00000013 -ffffffff809ac7e8,00000013 -ffffffff809ac8a0,00000013 -ffffffff809ac988,00000013 -ffffffff809acc00,00000013 -ffffffff809acd00,00000013 -ffffffff809acd88,00000013 -ffffffff809ad558,00000013 -ffffffff809ad600,00000013 -ffffffff809ad6e8,00000013 -ffffffff809af374,00000013 -ffffffff809b1d18,00000013 -ffffffff809b303c,00000013 -ffffffff809b3080,00000013 -ffffffff809b9700,00000013 -ffffffff809b97ec,00000013 -ffffffff809b993c,00000013 -ffffffff809b9a08,00000013 -ffffffff809b9b68,00000013 -ffffffff809b9c34,00000013 -ffffffff809ba1ec,00000013 -ffffffff809ba554,00000013 -ffffffff809bab64,00000013 -ffffffff809c8854,00000013 -ffffffff809c88e8,00000013 -ffffffff809c94c4,00000013 -ffffffff809c95c8,00000013 -ffffffff809c9b68,00000013 -ffffffff809c9cf4,00000013 -ffffffff809ca024,00000013 -ffffffff809cdda0,00000013 -ffffffff809ce4a4,00000013 -ffffffff809cefbc,00000013 -ffffffff809cf09c,00000013 -ffffffff809d08f4,00000013 -ffffffff809d0e04,00000013 -ffffffff809d0f08,00000013 -ffffffff809d0f9c,00000013 -ffffffff809d11c4,00000013 -ffffffff809d1468,00000013 -ffffffff809d1564,00000013 -ffffffff809d15cc,00000013 -ffffffff809d16a4,00000013 -ffffffff809d177c,00000013 -ffffffff809d1c94,00000013 -ffffffff809d1ee0,00000013 -ffffffff809d2114,00000013 -ffffffff809d22f8,00000013 -ffffffff809d23b4,00000013 -ffffffff809d2484,00000013 -ffffffff809d24bc,00000013 -ffffffff809d2564,00000013 -ffffffff809d2750,00000013 -ffffffff809d2830,00000013 -ffffffff809d2868,00000013 -ffffffff809d296c,00000013 -ffffffff809d2c58,00000013 -ffffffff809d2d8c,00000013 -ffffffff809d2eac,00000013 -ffffffff809d2f04,00000013 -ffffffff809d30b8,00000013 -ffffffff809d3124,00000013 -ffffffff809d3180,00000013 -ffffffff809d34a0,00000013 -ffffffff809d38ac,00000013 -ffffffff809d3994,00000013 -ffffffff809d3a68,00000013 -ffffffff809d42a8,00000013 -ffffffff809d4370,00000013 -ffffffff809d4440,00000013 -ffffffff809d4500,00000013 -ffffffff809d45d4,00000013 -ffffffff809d4680,00000013 -ffffffff809d47b4,00000013 -ffffffff809d4a74,00000013 -ffffffff809d4ac4,00000013 -ffffffff809d4c30,00000013 -ffffffff809d4d60,00000013 -ffffffff809d5174,00000013 -ffffffff809d51f0,00000013 -ffffffff809d5294,00000013 -ffffffff809d531c,00000013 -ffffffff809d5384,00000013 -ffffffff80a0106c,00000013 -ffffffff8001eb50,0980006f -ffffffff8001ed10,0260006f -ffffffff8001efc0,0260006f -ffffffff8001f080,0300006f -ffffffff8000c114,00000013 -ffffffff8000c470,00000013 -ffffffff8000c4cc,00000013 -ffffffff80689658,00000013 -ffffffff806899f0,00000013 -ffffffff80689a00,00000013 -ffffffff80689d6c,00000013 -ffffffff80689df4,00000013 -ffffffff8068a064,00000013 -ffffffff8068a13c,00000013 -ffffffff8068a218,00000013 -ffffffff8068a350,00000013 -ffffffff8068a444,00000013 -ffffffff8068a490,00000013 -ffffffff8068a4e4,00000013 -ffffffff8068a528,00000013 -ffffffff8068a610,00000013 -ffffffff8068a704,00000013 -ffffffff8068a9dc,00000013 -ffffffff8068abf4,00000013 -ffffffff8068ac44,00000013 -ffffffff8068ac48,00000013 -ffffffff8068b000,00000013 -ffffffff8068b03c,00000013 -ffffffff8068b170,00000013 -ffffffff8068b2c8,00000013 -ffffffff8068b3f8,00000013 -ffffffff8068b53c,00000013 -ffffffff8068b648,00000013 -ffffffff80a2f104,00000013 -ffffffff80a2f1bc,00000013 -ffffffff80a2f1e0,00000013 -ffffffff8007bd7c,00000013 -ffffffff80445794,01e0006f -ffffffff8044595c,01a0006f -ffffffff804455b4,01a0006f -ffffffff80445620,0180006f -ffffffff8044568c,01e0006f -ffffffff80445718,0200006f -ffffffff80445aa0,01a0006f -ffffffff804474cc,0180006f -ffffffff80447530,01a0006f -ffffffff804475b4,0120006f -ffffffff80447a74,0180006f -ffffffff80448274,01c0006f -ffffffff8044872c,0180006f -ffffffff80448570,01a0006f -ffffffff80448500,01a0006f -ffffffff80a2ebec,00000013 -ffffffff8001f6f0,0640006f -ffffffff800bfce0,00000013 -ffffffff800be94c,0120006f -ffffffff800bee00,00c0006f -ffffffff0168e450,00000013 -ffffffff0168e98c,00000013 -ffffffff016a6058,0160006f -ffffffff809ce16c,1980006f -ffffffff016a6040,0160006f -ffffffff8026ba00,0200006f -ffffffff016ac4f8,00000013 diff --git a/configs/linux.json b/configs/linux/linux.json similarity index 100% rename from configs/linux.json rename to configs/linux/linux.json diff --git a/configs/linux_firesim.json b/configs/linux/linux_firesim.json similarity index 100% rename from configs/linux_firesim.json rename to configs/linux/linux_firesim.json diff --git a/configs/linux_process_launch.json b/configs/linux/linux_process_launch.json similarity index 93% rename from configs/linux_process_launch.json rename to configs/linux/linux_process_launch.json index 564d962..8f2204f 100644 --- a/configs/linux_process_launch.json +++ b/configs/linux/linux_process_launch.json @@ -21,6 +21,7 @@ "receivers": { "txt": { "enabled": false, "path": "trace.test.txt" }, "prv_breakdown": { "enabled": true }, - "speedscope": { "enabled": true, "path": "trace.speedscope.json" } + "speedscope": { "enabled": true, "path": "trace.speedscope.json" }, + "bb_stats": { "enabled": false, "path": "trace.bb_stats.csv", "asid_of_interest": [106], "do_user": true} } } diff --git a/configs/linux_spec.json b/configs/linux_spec.json deleted file mode 100644 index d339d57..0000000 --- a/configs/linux_spec.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "encoded_trace": "/scratch/iansseijelly/FIRESIM_RUN_TMP/sim_slot_1/tacit0.out", - "application_binary_asid_tuples": [ - ["../spec2017/speckle/build/overlay/intspeed/test/641.leela_s/leela_s_base.riscv-64", "115"], - ["../spec2017/speckle/build/overlay/intspeed/test/641.leela_s/trace-submit", "113"], - ["../spec2017/speckle/build/overlay/intspeed/test/641.leela_s/trace-submit", "114"] - ], - "sbi_binary": "../firemarshal/images/firechip/spec17-intspeed-test-641.leela_s/spec17-intspeed-test-641.leela_s-bin", - "kernel_binary": "../firemarshal/images/firechip/spec17-intspeed-test-641.leela_s/spec17-intspeed-test-641.leela_s-bin-dwarf", - "kernel_jump_label_patch_log": "/scratch/iansseijelly/tacit-chipyard/sims/firesim/deploy/results-workload/2025-11-03--23-01-18-trace-hello/trace-hello-run-chores/jump_label_patch_map.txt", - "driver_binary_entry_tuples": [ - ["../firemarshal/boards/firechip/drivers/tacit-driver/tacit.o", "0xffffffff0169d000"], - ["../firemarshal/boards/firechip/drivers/iceblk-driver/iceblk.o", "0xffffffff016ac000"] - ], - "header_only": false, - "to_stats": false, - "to_txt": false, - "to_stack_txt": false, - "to_atomics": false, - "to_afdo": false, - "gcno": "", - "to_gcda": false, - "to_speedscope": false, - "to_perfetto": false, - "to_foc": false, - "to_vbb": false, - "to_path_profile": true -} diff --git a/configs/baremetal_foc.json b/configs/robotics/baremetal_foc.json similarity index 52% rename from configs/baremetal_foc.json rename to configs/robotics/baremetal_foc.json index 33f0760..62e46fe 100644 --- a/configs/baremetal_foc.json +++ b/configs/robotics/baremetal_foc.json @@ -5,16 +5,7 @@ "kernel_binary": "", "kernel_jump_label_patch_log": "", "driver_binary_entry_tuples": [], - "header_only": false, - "to_stats": false, - "to_txt": false, - "to_stack_txt": false, - "to_atomics": false, - "to_afdo": false, - "gcno": "", - "to_gcda": false, - "to_speedscope": true, - "to_perfetto": false, - "to_foc": false, - "to_vbb": true + "receivers": { + "speedscope": { "enabled": true, "path": "trace.foc.speedscope.json" } + } } diff --git a/configs/baremetal_freertos.json b/configs/robotics/baremetal_freertos.json similarity index 56% rename from configs/baremetal_freertos.json rename to configs/robotics/baremetal_freertos.json index 82e0ef6..be3c7e7 100644 --- a/configs/baremetal_freertos.json +++ b/configs/robotics/baremetal_freertos.json @@ -5,16 +5,7 @@ "kernel_binary": "", "kernel_jump_label_patch_log": "", "driver_binary_entry_tuples": [], - "header_only": false, - "to_stats": false, - "to_txt": false, - "to_stack_txt": false, - "to_atomics": false, - "to_afdo": false, - "gcno": "", - "to_gcda": false, - "to_speedscope": true, - "to_perfetto": false, - "to_foc": false, - "to_vbb": false + "receivers": { + "speedscope": { "enabled": true, "path": "trace.freertos.speedscope.json" } + } } diff --git a/configs/linux_600_perlbench.json b/configs/spec/linux_600_perlbench.json similarity index 100% rename from configs/linux_600_perlbench.json rename to configs/spec/linux_600_perlbench.json diff --git a/configs/linux_605_mcf.json b/configs/spec/linux_605_mcf.json similarity index 100% rename from configs/linux_605_mcf.json rename to configs/spec/linux_605_mcf.json diff --git a/configs/linux_625_x264.json b/configs/spec/linux_625_x264.json similarity index 100% rename from configs/linux_625_x264.json rename to configs/spec/linux_625_x264.json diff --git a/configs/linux_631_deepsjeng.json b/configs/spec/linux_631_deepsjeng.json similarity index 100% rename from configs/linux_631_deepsjeng.json rename to configs/spec/linux_631_deepsjeng.json diff --git a/configs/linux_641_leela.json b/configs/spec/linux_641_leela.json similarity index 100% rename from configs/linux_641_leela.json rename to configs/spec/linux_641_leela.json diff --git a/configs/linux_648_exchange2.json b/configs/spec/linux_648_exchange2.json similarity index 100% rename from configs/linux_648_exchange2.json rename to configs/spec/linux_648_exchange2.json diff --git a/src/backend/stats_receiver.rs b/src/backend/stats_receiver.rs deleted file mode 100644 index a1eb06a..0000000 --- a/src/backend/stats_receiver.rs +++ /dev/null @@ -1,109 +0,0 @@ -use crate::backend::abstract_receiver::{AbstractReceiver, BusReceiver}; -use crate::backend::event::{Entry, EventKind}; -use crate::frontend::br_mode; -use crate::frontend::runtime_cfg::DecoderRuntimeCfg; -use bus::BusReader; -use std::fs::File; -use std::io::{BufWriter, Write}; - -pub struct StatsReceiver { - writer: BufWriter, - receiver: BusReceiver, - runtime_cfg: DecoderRuntimeCfg, - file_size: u64, - packet_count: u64, - insn_count: u64, - hit_count: u64, - miss_count: u64, -} - -impl StatsReceiver { - pub fn new(bus_rx: BusReader, runtime_cfg: DecoderRuntimeCfg, file_size: u64) -> Self { - Self { - writer: BufWriter::new(File::create("trace.stats.txt").unwrap()), - receiver: BusReceiver { - name: "stats".to_string(), - bus_rx: bus_rx, - checksum: 0, - }, - packet_count: 0, - insn_count: 0, - hit_count: 0, - miss_count: 0, - runtime_cfg: runtime_cfg, - file_size: file_size, - } - } -} - -impl AbstractReceiver for StatsReceiver { - fn bus_rx(&mut self) -> &mut BusReader { - &mut self.receiver.bus_rx - } - - fn _bump_checksum(&mut self) { - self.receiver.checksum += 1; - } - - fn _receive_entry(&mut self, entry: Entry) { - match entry { - Entry::Event { kind, .. } => { - self.packet_count += 1; - match kind { - EventKind::BPHit { hit_count } => { - if self.runtime_cfg.br_mode == br_mode::BrMode::BrPredict { - self.hit_count += hit_count; - } - } - EventKind::BPMiss => { - if self.runtime_cfg.br_mode == br_mode::BrMode::BrPredict { - self.miss_count += 1; - } - } - _ => {} - } - } - Entry::Instruction { insn: _, pc: _ } => { - self.insn_count += 1; - } - } - } - - fn _flush(&mut self) { - self.writer - .write_all(format!("instruction count: {}\n", self.insn_count).as_bytes()) - .unwrap(); - self.writer - .write_all(format!("packet count: {}\n", self.packet_count).as_bytes()) - .unwrap(); - if self.runtime_cfg.br_mode == br_mode::BrMode::BrPredict { - self.writer - .write_all( - format!( - "hit rate: {:.2}%\n", - self.hit_count as f64 / (self.hit_count + self.miss_count) as f64 * 100.0 - ) - .as_bytes(), - ) - .unwrap(); - } - let bpi = self.file_size as f64 * 8.0 / self.insn_count as f64; //convert bytes to bits - self.writer - .write_all(format!("bits per instruction: {:.4}\n", bpi).as_bytes()) - .unwrap(); - self.writer - .write_all( - format!( - "trace payload size: {:.2}KiB\n", - self.file_size as f64 / 1024.0 - ) - .as_bytes(), - ) - .unwrap(); - let bpp = self.file_size as f64 * 8.0 / self.packet_count as f64; - self.writer - .write_all(format!("bits per packet: {:.4}\n", bpp).as_bytes()) - .unwrap(); - self.writer.flush().unwrap(); - } -} diff --git a/src/backend/afdo_receiver.rs b/src/receivers/afdo_receiver.rs similarity index 90% rename from src/backend/afdo_receiver.rs rename to src/receivers/afdo_receiver.rs index 9c7b1f9..8d78e8f 100644 --- a/src/backend/afdo_receiver.rs +++ b/src/receivers/afdo_receiver.rs @@ -1,4 +1,4 @@ -use crate::backend::abstract_receiver::{AbstractReceiver, BusReceiver}; +use crate::receivers::abstract_receiver::{AbstractReceiver, BusReceiver, Shared}; use crate::backend::event::{Entry, EventKind}; use bus::BusReader; use std::collections::HashMap; @@ -29,7 +29,20 @@ impl AfdoReceiver { elf_start: elf_start, } } +} + +pub fn factory( + _shared: &Shared, + _config: serde_json::Value, + bus_rx: BusReader, +) -> Box { + let elf_start = _config.get("elf_start").and_then(|value| value.as_u64()).unwrap_or(0); + Box::new(AfdoReceiver::new(bus_rx, elf_start)) +} +crate::register_receiver!("afdo", factory); + +impl AfdoReceiver { pub fn update_records(&mut self, from_addr: u64, to_addr: u64, timestamp: u64) { self.range_map .entry((self.last_record.1, to_addr)) diff --git a/src/backend/atomic_receiver.rs b/src/receivers/atomic_receiver.rs similarity index 86% rename from src/backend/atomic_receiver.rs rename to src/receivers/atomic_receiver.rs index cabe412..27f2517 100644 --- a/src/backend/atomic_receiver.rs +++ b/src/receivers/atomic_receiver.rs @@ -1,6 +1,6 @@ -use crate::backend::abstract_receiver::{AbstractReceiver, BusReceiver}; +use crate::receivers::abstract_receiver::{AbstractReceiver, BusReceiver, Shared}; use crate::backend::event::{Entry, EventKind}; -use crate::backend::stack_unwinder::{Frame, StackUnwinder, StackUpdateResult}; +use crate::receivers::stack_unwinder::{Frame, StackUnwinder, StackUpdateResult}; use crate::common::symbol_index::SymbolIndex; use bus::BusReader; use std::fs::File; @@ -31,7 +31,17 @@ impl AtomicReceiver { last_ts: 0, } } +} +pub fn factory( + _shared: &Shared, + _config: serde_json::Value, + bus_rx: BusReader, +) -> Box { + Box::new(AtomicReceiver::new(bus_rx, Arc::clone(&_shared.symbol_index))) +} +crate::register_receiver!("atomic", factory); +impl AtomicReceiver { fn is_atomic_insn(insn: &rvdasm::insn::Insn) -> bool { let name = insn.get_name(); name.starts_with("lr.") || name.starts_with("sc.") || name.starts_with("amo") diff --git a/src/receivers/bb_stats_receiver.rs b/src/receivers/bb_stats_receiver.rs index 31c5246..2ed568c 100644 --- a/src/receivers/bb_stats_receiver.rs +++ b/src/receivers/bb_stats_receiver.rs @@ -1,5 +1,6 @@ use crate::receivers::abstract_receiver::{AbstractReceiver, BusReceiver, Shared}; use crate::backend::event::{Entry, EventKind}; +use crate::common::prv::Prv; use bus::BusReader; use std::collections::HashMap; @@ -19,10 +20,13 @@ pub struct BBStatsReceiver { bb_records: HashMap>, prev_addr: u64, prev_timestamp: u64, + asid_of_interest: Vec, + prv_of_interest: Vec, + interested: bool } impl BBStatsReceiver { - pub fn new(bus_rx: BusReader, path: String) -> Self { + pub fn new(bus_rx: BusReader, path: String, asid_of_interest: Vec, prv_of_interest: Vec) -> Self { Self { writer: BufWriter::new(File::create(path).unwrap()), receiver: BusReceiver { @@ -33,6 +37,9 @@ impl BBStatsReceiver { bb_records: HashMap::new(), prev_addr: 0, prev_timestamp: 0, + asid_of_interest: asid_of_interest, + prv_of_interest: prv_of_interest, + interested: false, } } } @@ -43,7 +50,18 @@ pub fn factory( bus_rx: BusReader, ) -> Box { let path = _config.get("path").and_then(|value| value.as_str()).unwrap_or("trace.bb_stats.csv").to_string(); - Box::new(BBStatsReceiver::new(bus_rx, path)) + let asid_of_interest = _config.get("asid_of_interest").and_then(|value| value.as_array()).unwrap_or(&vec![]).iter().map(|value| value.as_u64().unwrap()).collect(); + let mut prv_of_interest = vec![]; + if _config.get("do_user").and_then(|value| value.as_bool()).unwrap_or(false) { + prv_of_interest.push(Prv::PrvUser); + } + if _config.get("do_supervisor").and_then(|value| value.as_bool()).unwrap_or(false) { + prv_of_interest.push(Prv::PrvSupervisor); + } + if _config.get("do_machine").and_then(|value| value.as_bool()).unwrap_or(false) { + prv_of_interest.push(Prv::PrvMachine); + } + Box::new(BBStatsReceiver::new(bus_rx, path, asid_of_interest, prv_of_interest)) } crate::register_receiver!("bb_stats", factory); @@ -116,6 +134,23 @@ impl AbstractReceiver for BBStatsReceiver { } => { self.update_bb_records(arc.0, arc.1, timestamp); } + Entry::Event { + timestamp, + kind: EventKind::Trap { reason, prv_arc, arc, ctx }, + } => { + if self.prv_of_interest.contains(&prv_arc.1) { + if prv_arc.1 == Prv::PrvUser { + if self.asid_of_interest.contains(&ctx.unwrap()) { + self.interested = true; + } + } else { + self.interested = true; + } + } + // drop the last bb, but update prev_addr and prev_timestamp + self.prev_addr = arc.1; + self.prev_timestamp = timestamp; + } _ => {} } } diff --git a/src/backend/gcda_receiver.rs b/src/receivers/gcda_receiver.rs similarity index 89% rename from src/backend/gcda_receiver.rs rename to src/receivers/gcda_receiver.rs index 57f65db..5786206 100644 --- a/src/backend/gcda_receiver.rs +++ b/src/receivers/gcda_receiver.rs @@ -1,4 +1,4 @@ -use crate::backend::abstract_receiver::{AbstractReceiver, BusReceiver}; +use crate::receivers::abstract_receiver::{AbstractReceiver, BusReceiver, Shared}; use crate::backend::event::{Entry, EventKind}; use addr2line::Loader; use bus::BusReader; @@ -62,7 +62,20 @@ impl GcdaReceiver { cfg: cfg, } } +} + +pub fn factory( + _shared: &Shared, + _config: serde_json::Value, + bus_rx: BusReader, +) -> Box { + let gcno_path = _config.get("gcno_path").and_then(|value| value.as_str()).unwrap_or("trace.gcno.txt").to_string(); + let elf_path = _config.get("elf_path").and_then(|value| value.as_str()).unwrap_or("trace.elf.txt").to_string(); + Box::new(GcdaReceiver::new(bus_rx, gcno_path, elf_path)) +} +crate::register_receiver!("gcda", factory); +impl GcdaReceiver { pub fn update_edge_map(&mut self, from_addr: u64, to_addr: u64) { let from_source: SourceLocation = SourceLocation::from_addr2line(self.loader.find_location(from_addr).unwrap()); diff --git a/src/receivers/mod.rs b/src/receivers/mod.rs index cc58029..51f0415 100644 --- a/src/receivers/mod.rs +++ b/src/receivers/mod.rs @@ -7,4 +7,10 @@ pub mod prv_breakdown_receiver; pub mod speedscope_receiver; pub mod stack_txt_receiver; pub mod bb_stats_receiver; -pub mod path_profile_receiver; \ No newline at end of file +pub mod path_profile_receiver; + +// TODO: mask off for now until verified again +// pub mod afdo_receiver; +// pub mod gcda_receiver; +// pub mod atomic_receiver; +// pub mod perfetto_receiver; \ No newline at end of file diff --git a/src/backend/perfetto_receiver.rs b/src/receivers/perfetto_receiver.rs similarity index 92% rename from src/backend/perfetto_receiver.rs rename to src/receivers/perfetto_receiver.rs index bf25c04..f88c782 100644 --- a/src/backend/perfetto_receiver.rs +++ b/src/receivers/perfetto_receiver.rs @@ -1,4 +1,4 @@ -use crate::backend::abstract_receiver::{AbstractReceiver, BusReceiver}; +use crate::receivers::abstract_receiver::{AbstractReceiver, BusReceiver, Shared}; use crate::backend::event::{Entry, EventKind}; use crate::backend::stack_unwinder::{Frame, StackUnwinder, StackUpdateResult}; use crate::common::symbol_index::SymbolIndex; @@ -40,7 +40,19 @@ impl PerfettoReceiver { last_ts: 0, } } +} + +pub fn factory( + _shared: &Shared, + _config: serde_json::Value, + bus_rx: BusReader, +) -> Box { + Box::new(PerfettoReceiver::new(bus_rx, Arc::clone(&_shared.symbol_index))) +} +crate::register_receiver!("perfetto", factory); + +impl PerfettoReceiver { fn drain_update(&mut self, ts: u64, update: StackUpdateResult) { for frame in update.frames_closed { self.emit_end(ts, &frame); From f60898ee762f0561ef8a1a6cf3463902d9139011 Mon Sep 17 00:00:00 2001 From: Lux Date: Tue, 3 Feb 2026 16:56:22 -0800 Subject: [PATCH 06/24] fix: minor minor fixes --- configs/linux/linux_process_launch.json | 18 +++++++++--------- src/receivers/bb_stats_receiver.rs | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/configs/linux/linux_process_launch.json b/configs/linux/linux_process_launch.json index 8f2204f..76c171f 100644 --- a/configs/linux/linux_process_launch.json +++ b/configs/linux/linux_process_launch.json @@ -2,14 +2,14 @@ "encoded_trace": "/scratch/iansseijelly/FIRESIM_RUN_TMP/sim_slot_1/tacit0.out", "application_binary_asid_tuples": [ ["../firemarshal/example-workloads/process-launch/overlay/root/process-launch/trace-submit", "106"], - ["../firemarshal/example-workloads/process-launch/overlay/root/process-launch/dummy", "107"], - ["../firemarshal/example-workloads/process-launch/overlay/root/process-launch/dummy", "108"], - ["../firemarshal/example-workloads/process-launch/overlay/root/process-launch/dummy", "109"], - ["../firemarshal/example-workloads/process-launch/overlay/root/process-launch/dummy", "110"], - ["../firemarshal/example-workloads/process-launch/overlay/root/process-launch/dummy", "111"], - ["../firemarshal/example-workloads/process-launch/overlay/root/process-launch/dummy", "112"], - ["../firemarshal/example-workloads/process-launch/overlay/root/process-launch/dummy", "113"], - ["../firemarshal/example-workloads/process-launch/overlay/root/process-launch/dummy", "114"] + ["../firemarshal/example-workloads/process-launch/overlay/root/process-launch/dummy", "237"], + ["../firemarshal/example-workloads/process-launch/overlay/root/process-launch/dummy", "238"], + ["../firemarshal/example-workloads/process-launch/overlay/root/process-launch/dummy", "239"], + ["../firemarshal/example-workloads/process-launch/overlay/root/process-launch/dummy", "240"], + ["../firemarshal/example-workloads/process-launch/overlay/root/process-launch/dummy", "241"], + ["../firemarshal/example-workloads/process-launch/overlay/root/process-launch/dummy", "242"], + ["../firemarshal/example-workloads/process-launch/overlay/root/process-launch/dummy", "243"], + ["../firemarshal/example-workloads/process-launch/overlay/root/process-launch/dummy", "244"] ], "sbi_binary": "../firemarshal/images/firechip/process-launch/process-launch-bin", "kernel_binary": "../firemarshal/images/firechip/process-launch/process-launch-bin-dwarf", @@ -22,6 +22,6 @@ "txt": { "enabled": false, "path": "trace.test.txt" }, "prv_breakdown": { "enabled": true }, "speedscope": { "enabled": true, "path": "trace.speedscope.json" }, - "bb_stats": { "enabled": false, "path": "trace.bb_stats.csv", "asid_of_interest": [106], "do_user": true} + "bb_stats": { "enabled": false, "path": "trace.bb_stats.csv", "do_supervisor": true} } } diff --git a/src/receivers/bb_stats_receiver.rs b/src/receivers/bb_stats_receiver.rs index 2ed568c..22a480a 100644 --- a/src/receivers/bb_stats_receiver.rs +++ b/src/receivers/bb_stats_receiver.rs @@ -136,7 +136,7 @@ impl AbstractReceiver for BBStatsReceiver { } Entry::Event { timestamp, - kind: EventKind::Trap { reason, prv_arc, arc, ctx }, + kind: EventKind::Trap { reason: _, prv_arc, arc, ctx }, } => { if self.prv_of_interest.contains(&prv_arc.1) { if prv_arc.1 == Prv::PrvUser { From 97b06fffdc5887bca6ea6e156d77ed690022aef7 Mon Sep 17 00:00:00 2001 From: Lux Date: Tue, 3 Feb 2026 16:56:38 -0800 Subject: [PATCH 07/24] add: a helper for plotting a distribution --- scripts/plot_distribution.py | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 scripts/plot_distribution.py diff --git a/scripts/plot_distribution.py b/scripts/plot_distribution.py new file mode 100644 index 0000000..175a155 --- /dev/null +++ b/scripts/plot_distribution.py @@ -0,0 +1,33 @@ +# Given a sequence of iter: time pairs, plot the distribution of the times. + +import matplotlib.pyplot as plt +import numpy as np +import pandas as pd +import argparse +import re + +pattern = r'(\d+): (\d+)' + +def plot_distribution(input_file: str) -> None: + with open(input_file, 'r') as f: + content = f.read() + matches = re.findall(pattern, content) + times = [int(match[1]) for match in matches] + plt.hist(times, bins=100) + + print(f'{input_file}: {min(times)} to {max(times)}') + print(f'{input_file}: {sum(times) / len(times)} average') + print(f'{input_file}: {np.median(times)} median') + print(f'{input_file}: {np.percentile(times, 25)} 25th percentile') + print(f'{input_file}: {np.percentile(times, 75)} 75th percentile') + print(f'{input_file}: {np.percentile(times, 90)} 90th percentile') + print(f'{input_file}: {np.percentile(times, 95)} 95th percentile') + print(f'{input_file}: {np.percentile(times, 99)} 99th percentile') + + plt.savefig(f'{input_file}.png') + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument('--input', type=str, required=True) + args = parser.parse_args() + plot_distribution(args.input) \ No newline at end of file From 1b7aca6d0569a1e70d91e2deff8bf32f22afb1e0 Mon Sep 17 00:00:00 2001 From: Lux Date: Tue, 3 Feb 2026 21:41:22 -0800 Subject: [PATCH 08/24] refactor: update configuration json structure --- .../baremetal_hello/baremetal_firesim.json | 4 +- .../baremetal_hello/baremetal_hello_boom.json | 4 +- .../baremetal_hello_spike.json | 4 +- configs/baremetal_hello/baremetal_rocket.json | 4 +- configs/embench/baremetal_crc32.json | 4 +- configs/embench/baremetal_edn.json | 4 +- configs/embench/baremetal_huffbench.json | 4 +- configs/embench/baremetal_nettlesha256.json | 4 +- configs/embench/baremetal_wikisort.json | 4 +- configs/linux/linux.json | 23 ++--- configs/linux/linux_firesim.json | 24 ++--- configs/linux/linux_process_launch.json | 15 +-- configs/robotics/baremetal_foc.json | 4 +- configs/robotics/baremetal_freertos.json | 4 +- configs/spec/linux_600_perlbench.json | 72 +-------------- configs/spec/linux_605_mcf.json | 22 ++--- configs/spec/linux_625_x264.json | 22 ++--- configs/spec/linux_631_deepsjeng.json | 22 ++--- configs/spec/linux_641_leela.json | 20 +--- configs/spec/linux_648_exchange2.json | 22 ++--- src/common/insn_index.rs | 26 ++++-- src/common/static_cfg.rs | 25 +++-- src/common/symbol_index.rs | 48 ++++++---- src/frontend/decoder.rs | 20 ++-- src/main.rs | 46 ++++------ src/receivers/speedscope_receiver.rs | 92 +++++++++++++++---- src/receivers/stack_unwinder.rs | 4 + 27 files changed, 241 insertions(+), 306 deletions(-) diff --git a/configs/baremetal_hello/baremetal_firesim.json b/configs/baremetal_hello/baremetal_firesim.json index 6c3497a..dcf5cf2 100644 --- a/configs/baremetal_hello/baremetal_firesim.json +++ b/configs/baremetal_hello/baremetal_firesim.json @@ -1,7 +1,7 @@ { "encoded_trace": "/scratch/iansseijelly/FIRESIM_RUN_TMP/sim_slot_0/tacit0.out", - "application_binary_asid_tuples": [], - "sbi_binary": "../firemarshal/example-workloads/bare-hello/trace-hello.elf", + "user_binaries": [], + "machine_binary": "../firemarshal/example-workloads/bare-hello/trace-hello.elf", "kernel_binary": "", "kernel_jump_label_patch_log": "", "driver_binary_entry_tuples": [], diff --git a/configs/baremetal_hello/baremetal_hello_boom.json b/configs/baremetal_hello/baremetal_hello_boom.json index 0e1391b..ecf8f25 100644 --- a/configs/baremetal_hello/baremetal_hello_boom.json +++ b/configs/baremetal_hello/baremetal_hello_boom.json @@ -1,7 +1,7 @@ { "encoded_trace": "../../sims/vcs/trace_monitor_boom_tile_0.encoded.trace", - "application_binary_asid_tuples": [], - "sbi_binary": "../baremetal-ide/build/examples/pmu-tests/trace-hello.elf", + "user_binaries": [], + "machine_binary": "../baremetal-ide/build/examples/pmu-tests/trace-hello.elf", "kernel_binary": "", "kernel_jump_label_patch_log": "", "driver_binary_entry_tuples": [], diff --git a/configs/baremetal_hello/baremetal_hello_spike.json b/configs/baremetal_hello/baremetal_hello_spike.json index 760ba04..10cee80 100644 --- a/configs/baremetal_hello/baremetal_hello_spike.json +++ b/configs/baremetal_hello/baremetal_hello_spike.json @@ -1,7 +1,7 @@ { "encoded_trace": "../baremetal-ide/build/tmp/tacit.out", - "application_binary_asid_tuples": [], - "sbi_binary": "../baremetal-ide/build/examples/pmu-tests/trace-hello.elf", + "user_binaries": [], + "machine_binary": "../baremetal-ide/build/examples/pmu-tests/trace-hello.elf", "kernel_binary": "", "kernel_jump_label_patch_log": "", "driver_binary_entry_tuples": [], diff --git a/configs/baremetal_hello/baremetal_rocket.json b/configs/baremetal_hello/baremetal_rocket.json index 4ddac91..99a8440 100644 --- a/configs/baremetal_hello/baremetal_rocket.json +++ b/configs/baremetal_hello/baremetal_rocket.json @@ -1,7 +1,7 @@ { "encoded_trace": "../../sims/vcs/trace_monitor_rockettile_0.encoded.trace", - "application_binary_asid_tuples": [], - "sbi_binary": "../baremetal-ide/build/examples/pmu-tests/trace-hello.elf", + "user_binaries": [], + "machine_binary": "../baremetal-ide/build/examples/pmu-tests/trace-hello.elf", "kernel_binary": "", "kernel_jump_label_patch_log": "", "driver_binary_entry_tuples": [], diff --git a/configs/embench/baremetal_crc32.json b/configs/embench/baremetal_crc32.json index 1cc040a..9d357fe 100644 --- a/configs/embench/baremetal_crc32.json +++ b/configs/embench/baremetal_crc32.json @@ -1,7 +1,7 @@ { "encoded_trace": "../../sims/vcs/trace_monitor_rockettile_0.encoded.trace", - "application_binary_asid_tuples": [], - "sbi_binary": "../baremetal-ide/build/examples/embench/crc32.elf", + "user_binaries": [], + "machine_binary": "../baremetal-ide/build/examples/embench/crc32.elf", "kernel_binary": "", "kernel_jump_label_patch_log": "", "driver_binary_entry_tuples": [], diff --git a/configs/embench/baremetal_edn.json b/configs/embench/baremetal_edn.json index 9cf02b1..8336a92 100644 --- a/configs/embench/baremetal_edn.json +++ b/configs/embench/baremetal_edn.json @@ -1,7 +1,7 @@ { "encoded_trace": "../../sims/vcs/trace_monitor_rockettile_0.encoded.trace", - "application_binary_asid_tuples": [], - "sbi_binary": "../baremetal-ide/build/examples/embench/edn.elf", + "user_binaries": [], + "machine_binary": "../baremetal-ide/build/examples/embench/edn.elf", "kernel_binary": "", "kernel_jump_label_patch_log": "", "driver_binary_entry_tuples": [], diff --git a/configs/embench/baremetal_huffbench.json b/configs/embench/baremetal_huffbench.json index 7b0bbeb..755e41e 100644 --- a/configs/embench/baremetal_huffbench.json +++ b/configs/embench/baremetal_huffbench.json @@ -1,7 +1,7 @@ { "encoded_trace": "../../sims/vcs/trace_monitor_rockettile_0.encoded.trace", - "application_binary_asid_tuples": [], - "sbi_binary": "../baremetal-ide/build/examples/embench/huffbench.elf", + "user_binaries": [], + "machine_binary": "../baremetal-ide/build/examples/embench/huffbench.elf", "kernel_binary": "", "kernel_jump_label_patch_log": "", "driver_binary_entry_tuples": [], diff --git a/configs/embench/baremetal_nettlesha256.json b/configs/embench/baremetal_nettlesha256.json index 1f37431..3e5d9c4 100644 --- a/configs/embench/baremetal_nettlesha256.json +++ b/configs/embench/baremetal_nettlesha256.json @@ -1,7 +1,7 @@ { "encoded_trace": "../../sims/vcs/trace_monitor_rockettile_0.encoded.trace", - "application_binary_asid_tuples": [], - "sbi_binary": "../baremetal-ide/build/examples/embench/nettle-sha256.elf", + "user_binaries": [], + "machine_binary": "../baremetal-ide/build/examples/embench/nettle-sha256.elf", "kernel_binary": "", "kernel_jump_label_patch_log": "", "driver_binary_entry_tuples": [], diff --git a/configs/embench/baremetal_wikisort.json b/configs/embench/baremetal_wikisort.json index 74315eb..47a53ba 100644 --- a/configs/embench/baremetal_wikisort.json +++ b/configs/embench/baremetal_wikisort.json @@ -1,7 +1,7 @@ { "encoded_trace": "../../sims/vcs/trace_monitor_rockettile_0.encoded.trace", - "application_binary_asid_tuples": [], - "sbi_binary": "../baremetal-ide/build/examples/embench/wikisort.elf", + "user_binaries": [], + "machine_binary": "../baremetal-ide/build/examples/embench/wikisort.elf", "kernel_binary": "", "kernel_jump_label_patch_log": "", "driver_binary_entry_tuples": [], diff --git a/configs/linux/linux.json b/configs/linux/linux.json index 50e0809..bc16ba2 100644 --- a/configs/linux/linux.json +++ b/configs/linux/linux.json @@ -1,26 +1,17 @@ { "encoded_trace": "../firemarshal/tacit.out", - "application_binary_asid_tuples": [ - ["../firemarshal/example-workloads/trace-hello/overlay/root/trace-hello/hello", "108"], - ["../firemarshal/example-workloads/trace-hello/overlay/root/trace-hello/trace-submit", "106"] + "user_binaries": [ + {"binary": "../firemarshal/example-workloads/trace-hello/overlay/root/trace-hello/hello", "asids": [108]}, + {"binary": "../firemarshal/example-workloads/trace-hello/overlay/root/trace-hello/trace-submit", "asids": [106]} ], - "sbi_binary": "../firemarshal/images/firechip/trace-hello/trace-hello-bin", + "machine_binary": "../firemarshal/images/firechip/trace-hello/trace-hello-bin", "kernel_binary": "../firemarshal/images/firechip/trace-hello/trace-hello-bin-dwarf", "kernel_jump_label_patch_log": "/scratch/iansseijelly/tacit-chipyard/software/firemarshal/runOutput/trace-hello-launch-2025-10-14--17-58-54-65BQBFWUG5A8C1JN/trace-hello-run-chores/jump_label_patch_map.txt", "driver_binary_entry_tuples": [ ["../firemarshal/images/firechip/trace-hello/tacit-dwarf", "0xffffffff0169d000"], ["../firemarshal/images/firechip/trace-hello/iceblk-dwarf", "0xffffffff016ac000"] ], - "header_only": false, - "to_stats": false, - "to_txt": true, - "to_stack_txt": false, - "to_atomics": false, - "to_afdo": false, - "gcno": "", - "to_gcda": false, - "to_speedscope": false, - "to_perfetto": false, - "to_foc": false, - "to_vbb": false + "receivers": { + "speedscope": { "enabled": true, "path": "trace.speedscope.json" } + } } diff --git a/configs/linux/linux_firesim.json b/configs/linux/linux_firesim.json index 480f969..34dd321 100644 --- a/configs/linux/linux_firesim.json +++ b/configs/linux/linux_firesim.json @@ -1,27 +1,17 @@ { "encoded_trace": "/scratch/iansseijelly/FIRESIM_RUN_TMP/sim_slot_1/tacit0.out", - "application_binary_asid_tuples": [ - ["../firemarshal/example-workloads/trace-hello/overlay/root/trace-hello/hello", "108"], - ["../firemarshal/example-workloads/trace-hello/overlay/root/trace-hello/trace-submit", "106"], - ["../firemarshal/example-workloads/trace-hello/overlay/root/trace-hello/trace-submit", "107"] + "user_binaries": [ + {"binary": "../firemarshal/example-workloads/trace-hello/overlay/root/trace-hello/hello", "asids": [108]}, + {"binary": "../firemarshal/example-workloads/trace-hello/overlay/root/trace-hello/trace-submit", "asids": [106, 107]} ], - "sbi_binary": "../firemarshal/images/firechip/trace-hello/trace-hello-bin", + "machine_binary": "../firemarshal/images/firechip/trace-hello/trace-hello-bin", "kernel_binary": "../firemarshal/images/firechip/trace-hello/trace-hello-bin-dwarf", "kernel_jump_label_patch_log": "/scratch/iansseijelly/tacit-chipyard/sims/firesim/deploy/results-workload/2026-01-06--05-35-54-trace-hello/trace-hello-run-chores/jump_label_patch_map.txt", "driver_binary_entry_tuples": [ ["../firemarshal/images/firechip/trace-hello/tacit-dwarf", "0xffffffff0169d000"], ["../firemarshal/images/firechip/trace-hello/iceblk-dwarf", "0xffffffff016ac000"] ], - "header_only": false, - "to_stats": false, - "to_txt": true, - "to_stack_txt": true, - "to_atomics": false, - "to_afdo": false, - "gcno": "", - "to_gcda": false, - "to_speedscope": true, - "to_perfetto": false, - "to_foc": false, - "to_vbb": false + "receivers": { + "speedscope": { "enabled": true, "path": "trace.speedscope.json" } + } } diff --git a/configs/linux/linux_process_launch.json b/configs/linux/linux_process_launch.json index 76c171f..aaba70a 100644 --- a/configs/linux/linux_process_launch.json +++ b/configs/linux/linux_process_launch.json @@ -1,17 +1,10 @@ { "encoded_trace": "/scratch/iansseijelly/FIRESIM_RUN_TMP/sim_slot_1/tacit0.out", - "application_binary_asid_tuples": [ - ["../firemarshal/example-workloads/process-launch/overlay/root/process-launch/trace-submit", "106"], - ["../firemarshal/example-workloads/process-launch/overlay/root/process-launch/dummy", "237"], - ["../firemarshal/example-workloads/process-launch/overlay/root/process-launch/dummy", "238"], - ["../firemarshal/example-workloads/process-launch/overlay/root/process-launch/dummy", "239"], - ["../firemarshal/example-workloads/process-launch/overlay/root/process-launch/dummy", "240"], - ["../firemarshal/example-workloads/process-launch/overlay/root/process-launch/dummy", "241"], - ["../firemarshal/example-workloads/process-launch/overlay/root/process-launch/dummy", "242"], - ["../firemarshal/example-workloads/process-launch/overlay/root/process-launch/dummy", "243"], - ["../firemarshal/example-workloads/process-launch/overlay/root/process-launch/dummy", "244"] + "user_binaries": [ + {"binary": "../firemarshal/example-workloads/process-launch/overlay/root/process-launch/trace-submit", "asids": [106]}, + {"binary": "../firemarshal/example-workloads/process-launch/overlay/root/process-launch/dummy", "asids": [677, 678, 679, 680, 681, 682, 683, 684]} ], - "sbi_binary": "../firemarshal/images/firechip/process-launch/process-launch-bin", + "machine_binary": "../firemarshal/images/firechip/process-launch/process-launch-bin", "kernel_binary": "../firemarshal/images/firechip/process-launch/process-launch-bin-dwarf", "kernel_jump_label_patch_log": "/scratch/iansseijelly/tacit-chipyard/sims/firesim/deploy/results-workload/2026-01-28--19-09-05-process-launch/process-launch-run-chores/jump_label_patch_map.txt", "driver_binary_entry_tuples": [ diff --git a/configs/robotics/baremetal_foc.json b/configs/robotics/baremetal_foc.json index 62e46fe..c71336c 100644 --- a/configs/robotics/baremetal_foc.json +++ b/configs/robotics/baremetal_foc.json @@ -1,7 +1,7 @@ { "encoded_trace": "../../sims/vcs/trace_monitor_rockettile_0.encoded.trace", - "application_binary_asid_tuples": [], - "sbi_binary": "../baremetal-ide/build/examples/foc/foc.elf", + "user_binaries": [], + "machine_binary": "../baremetal-ide/build/examples/foc/foc.elf", "kernel_binary": "", "kernel_jump_label_patch_log": "", "driver_binary_entry_tuples": [], diff --git a/configs/robotics/baremetal_freertos.json b/configs/robotics/baremetal_freertos.json index be3c7e7..99138c5 100644 --- a/configs/robotics/baremetal_freertos.json +++ b/configs/robotics/baremetal_freertos.json @@ -1,7 +1,7 @@ { "encoded_trace": "/scratch/iansseijelly/tacit-chipyard/software/baremetal-ide/tacit.out", - "application_binary_asid_tuples": [], - "sbi_binary": "../../software/baremetal-ide/build/examples/freertos/freertos_demo.elf", + "user_binaries": [], + "machine_binary": "../../software/baremetal-ide/build/examples/freertos/freertos_demo.elf", "kernel_binary": "", "kernel_jump_label_patch_log": "", "driver_binary_entry_tuples": [], diff --git a/configs/spec/linux_600_perlbench.json b/configs/spec/linux_600_perlbench.json index 46baf59..5b269c3 100644 --- a/configs/spec/linux_600_perlbench.json +++ b/configs/spec/linux_600_perlbench.json @@ -1,76 +1,14 @@ { "encoded_trace": "/scratch/iansseijelly/FIRESIM_RUN_TMP/sim_slot_0/tacit0.out", - "application_binary_asid_tuples": [ - ["../spec2017/speckle/build/overlay/intspeed/test/600.perlbench_s/perlbench_s_base.riscv-64", "127"], - ["../spec2017/speckle/build/overlay/intspeed/test/600.perlbench_s/perlbench_s_base.riscv-64", "123"], - ["../spec2017/speckle/build/overlay/intspeed/test/600.perlbench_s/perlbench_s_base.riscv-64", "189"], - ["../spec2017/speckle/build/overlay/intspeed/test/600.perlbench_s/perlbench_s_base.riscv-64", "201"], - ["../spec2017/speckle/build/overlay/intspeed/test/600.perlbench_s/perlbench_s_base.riscv-64", "181"], - ["../spec2017/speckle/build/overlay/intspeed/test/600.perlbench_s/perlbench_s_base.riscv-64", "183"], - ["../spec2017/speckle/build/overlay/intspeed/test/600.perlbench_s/perlbench_s_base.riscv-64", "213"], - ["../spec2017/speckle/build/overlay/intspeed/test/600.perlbench_s/perlbench_s_base.riscv-64", "182"], - ["../spec2017/speckle/build/overlay/intspeed/test/600.perlbench_s/perlbench_s_base.riscv-64", "163"], - ["../spec2017/speckle/build/overlay/intspeed/test/600.perlbench_s/perlbench_s_base.riscv-64", "145"], - ["../spec2017/speckle/build/overlay/intspeed/test/600.perlbench_s/perlbench_s_base.riscv-64", "125"], - ["../spec2017/speckle/build/overlay/intspeed/test/600.perlbench_s/perlbench_s_base.riscv-64", "159"], - ["../spec2017/speckle/build/overlay/intspeed/test/600.perlbench_s/perlbench_s_base.riscv-64", "207"], - ["../spec2017/speckle/build/overlay/intspeed/test/600.perlbench_s/perlbench_s_base.riscv-64", "167"], - ["../spec2017/speckle/build/overlay/intspeed/test/600.perlbench_s/perlbench_s_base.riscv-64", "203"], - ["../spec2017/speckle/build/overlay/intspeed/test/600.perlbench_s/perlbench_s_base.riscv-64", "206"], - ["../spec2017/speckle/build/overlay/intspeed/test/600.perlbench_s/perlbench_s_base.riscv-64", "165"], - ["../spec2017/speckle/build/overlay/intspeed/test/600.perlbench_s/perlbench_s_base.riscv-64", "209"], - ["../spec2017/speckle/build/overlay/intspeed/test/600.perlbench_s/perlbench_s_base.riscv-64", "129"], - ["../spec2017/speckle/build/overlay/intspeed/test/600.perlbench_s/perlbench_s_base.riscv-64", "121"], - ["../spec2017/speckle/build/overlay/intspeed/test/600.perlbench_s/perlbench_s_base.riscv-64", "191"], - ["../spec2017/speckle/build/overlay/intspeed/test/600.perlbench_s/perlbench_s_base.riscv-64", "195"], - ["../spec2017/speckle/build/overlay/intspeed/test/600.perlbench_s/perlbench_s_base.riscv-64", "142"], - ["../spec2017/speckle/build/overlay/intspeed/test/600.perlbench_s/perlbench_s_base.riscv-64", "143"], - ["../spec2017/speckle/build/overlay/intspeed/test/600.perlbench_s/perlbench_s_base.riscv-64", "205"], - ["../spec2017/speckle/build/overlay/intspeed/test/600.perlbench_s/perlbench_s_base.riscv-64", "187"], - ["../spec2017/speckle/build/overlay/intspeed/test/600.perlbench_s/perlbench_s_base.riscv-64", "161"], - ["../spec2017/speckle/build/overlay/intspeed/test/600.perlbench_s/perlbench_s_base.riscv-64", "197"], - ["../spec2017/speckle/build/overlay/intspeed/test/600.perlbench_s/perlbench_s_base.riscv-64", "199"], - ["../spec2017/speckle/build/overlay/intspeed/test/600.perlbench_s/perlbench_s_base.riscv-64", "137"], - ["../spec2017/speckle/build/overlay/intspeed/test/600.perlbench_s/perlbench_s_base.riscv-64", "171"], - ["../spec2017/speckle/build/overlay/intspeed/test/600.perlbench_s/perlbench_s_base.riscv-64", "131"], - ["../spec2017/speckle/build/overlay/intspeed/test/600.perlbench_s/perlbench_s_base.riscv-64", "153"], - ["../spec2017/speckle/build/overlay/intspeed/test/600.perlbench_s/perlbench_s_base.riscv-64", "193"], - ["../spec2017/speckle/build/overlay/intspeed/test/600.perlbench_s/perlbench_s_base.riscv-64", "141"], - ["../spec2017/speckle/build/overlay/intspeed/test/600.perlbench_s/perlbench_s_base.riscv-64", "135"], - ["../spec2017/speckle/build/overlay/intspeed/test/600.perlbench_s/perlbench_s_base.riscv-64", "149"], - ["../spec2017/speckle/build/overlay/intspeed/test/600.perlbench_s/perlbench_s_base.riscv-64", "169"], - ["../spec2017/speckle/build/overlay/intspeed/test/600.perlbench_s/perlbench_s_base.riscv-64", "130"], - ["../spec2017/speckle/build/overlay/intspeed/test/600.perlbench_s/perlbench_s_base.riscv-64", "147"], - ["../spec2017/speckle/build/overlay/intspeed/test/600.perlbench_s/perlbench_s_base.riscv-64", "151"], - ["../spec2017/speckle/build/overlay/intspeed/test/600.perlbench_s/perlbench_s_base.riscv-64", "185"], - ["../spec2017/speckle/build/overlay/intspeed/test/600.perlbench_s/perlbench_s_base.riscv-64", "133"], - ["../spec2017/speckle/build/overlay/intspeed/test/600.perlbench_s/perlbench_s_base.riscv-64", "173"], - ["../spec2017/speckle/build/overlay/intspeed/test/600.perlbench_s/perlbench_s_base.riscv-64", "150"], - ["../spec2017/speckle/build/overlay/intspeed/test/600.perlbench_s/perlbench_s_base.riscv-64", "177"], - ["../spec2017/speckle/build/overlay/intspeed/test/600.perlbench_s/perlbench_s_base.riscv-64", "139"], - ["../spec2017/speckle/build/overlay/intspeed/test/600.perlbench_s/perlbench_s_base.riscv-64", "157"], - ["../spec2017/speckle/build/overlay/intspeed/test/600.perlbench_s/perlbench_s_base.riscv-64", "179"], - ["../spec2017/speckle/build/overlay/intspeed/test/600.perlbench_s/perlbench_s_base.riscv-64", "211"], - ["../spec2017/speckle/build/overlay/intspeed/test/600.perlbench_s/perlbench_s_base.riscv-64", "175"] - ], - "sbi_binary": "../firemarshal/images/firechip/spec17-intspeed-test-600.perlbench_s/spec17-intspeed-test-600.perlbench_s-bin", + "user_binaries": [], + "machine_binary": "../firemarshal/images/firechip/spec17-intspeed-test-600.perlbench_s/spec17-intspeed-test-600.perlbench_s-bin", "kernel_binary": "../firemarshal/images/firechip/spec17-intspeed-test-600.perlbench_s/spec17-intspeed-test-600.perlbench_s-bin-dwarf", "kernel_jump_label_patch_log": "/scratch/iansseijelly/tacit-chipyard/sims/firesim/deploy/results-workload/2025-11-15--01-13-55-spec17-intspeed-test-605/spec17-intspeed-test-605-run-chores/jump_label_patch_map.txt", "driver_binary_entry_tuples": [ ["../firemarshal/boards/firechip/drivers/tacit-driver/tacit.o", "0xffffffff0169d000"], ["../firemarshal/boards/firechip/drivers/iceblk-driver/iceblk.o", "0xffffffff016ac000"] ], - "header_only": false, - "to_stats": false, - "to_txt": false, - "to_stack_txt": false, - "to_atomics": false, - "to_afdo": false, - "gcno": "", - "to_gcda": false, - "to_speedscope": false, - "to_perfetto": false, - "to_foc": false, - "to_vbb": true, - "to_path_profile": false + "receivers": { + "bb_stats": { "enabled": true, "path": "trace.bb_stats.csv", "do_user": true} + } } diff --git a/configs/spec/linux_605_mcf.json b/configs/spec/linux_605_mcf.json index ae4b92d..de8c6e6 100644 --- a/configs/spec/linux_605_mcf.json +++ b/configs/spec/linux_605_mcf.json @@ -1,26 +1,16 @@ { "encoded_trace": "/scratch/iansseijelly/FIRESIM_RUN_TMP/sim_slot_1/tacit0.out", - "application_binary_asid_tuples": [ - ["../spec2017/speckle/build/overlay/intspeed/test/605.mcf_s/mcf_s_base.riscv-64", "117"] + "user_binaries": [ + {"binary": "../spec2017/speckle/build/overlay/intspeed/test/605.mcf_s/mcf_s_base.riscv-64", "asids": [117]} ], - "sbi_binary": "../firemarshal/images/firechip/spec17-intspeed-test-605-605.mcf_s/spec17-intspeed-test-605-605.mcf_s-bin", + "machine_binary": "../firemarshal/images/firechip/spec17-intspeed-test-605-605.mcf_s/spec17-intspeed-test-605-605.mcf_s-bin", "kernel_binary": "../firemarshal/images/firechip/spec17-intspeed-test-605-605.mcf_s/spec17-intspeed-test-605-605.mcf_s-bin-dwarf", "kernel_jump_label_patch_log": "/scratch/iansseijelly/tacit-chipyard/sims/firesim/deploy/results-workload/2025-11-15--01-13-55-spec17-intspeed-test-605/spec17-intspeed-test-605-run-chores/jump_label_patch_map.txt", "driver_binary_entry_tuples": [ ["../firemarshal/boards/firechip/drivers/tacit-driver/tacit.o", "0xffffffff0169d000"], ["../firemarshal/boards/firechip/drivers/iceblk-driver/iceblk.o", "0xffffffff016ac000"] ], - "header_only": false, - "to_stats": false, - "to_txt": false, - "to_stack_txt": false, - "to_atomics": false, - "to_afdo": false, - "gcno": "", - "to_gcda": false, - "to_speedscope": false, - "to_perfetto": false, - "to_foc": false, - "to_vbb": true, - "to_path_profile": false + "receivers": { + "bb_stats": { "enabled": true, "path": "trace.bb_stats.csv", "do_user": true} + } } diff --git a/configs/spec/linux_625_x264.json b/configs/spec/linux_625_x264.json index 602351b..e9e2c16 100644 --- a/configs/spec/linux_625_x264.json +++ b/configs/spec/linux_625_x264.json @@ -1,26 +1,16 @@ { "encoded_trace": "/scratch/iansseijelly/FIRESIM_RUN_TMP/sim_slot_0/tacit0.out", - "application_binary_asid_tuples": [ - ["../spec2017/speckle/build/overlay/intspeed/test/625.x264_s/x264_s_base.riscv-64", "117"] + "user_binaries": [ + {"binary": "../spec2017/speckle/build/overlay/intspeed/test/625.x264_s/x264_s_base.riscv-64", "asids": [117]} ], - "sbi_binary": "../firemarshal/images/firechip/spec17-intspeed-test-625.x264_s/spec17-intspeed-test-625.x264_s-bin", + "machine_binary": "../firemarshal/images/firechip/spec17-intspeed-test-625.x264_s/spec17-intspeed-test-625.x264_s-bin", "kernel_binary": "../firemarshal/images/firechip/spec17-intspeed-test-625.x264_s/spec17-intspeed-test-625.x264_s-bin-dwarf", "kernel_jump_label_patch_log": "/scratch/iansseijelly/tacit-chipyard/sims/firesim/deploy/results-workload/2025-11-15--01-13-55-spec17-intspeed-test-605/spec17-intspeed-test-605-run-chores/jump_label_patch_map.txt", "driver_binary_entry_tuples": [ ["../firemarshal/boards/firechip/drivers/tacit-driver/tacit.o", "0xffffffff0169d000"], ["../firemarshal/boards/firechip/drivers/iceblk-driver/iceblk.o", "0xffffffff016ac000"] ], - "header_only": false, - "to_stats": false, - "to_txt": false, - "to_stack_txt": false, - "to_atomics": false, - "to_afdo": false, - "gcno": "", - "to_gcda": false, - "to_speedscope": false, - "to_perfetto": false, - "to_foc": false, - "to_vbb": true, - "to_path_profile": false + "receivers": { + "bb_stats": { "enabled": true, "path": "trace.bb_stats.csv", "do_user": true} + } } diff --git a/configs/spec/linux_631_deepsjeng.json b/configs/spec/linux_631_deepsjeng.json index aa09fa0..e604631 100644 --- a/configs/spec/linux_631_deepsjeng.json +++ b/configs/spec/linux_631_deepsjeng.json @@ -1,26 +1,16 @@ { "encoded_trace": "/scratch/iansseijelly/FIRESIM_RUN_TMP/sim_slot_0/tacit0.out", - "application_binary_asid_tuples": [ - ["../spec2017/speckle/build/overlay/intspeed/test/631.deepsjeng_s/deepsjeng_s_base.riscv-64", "117"] + "user_binaries": [ + {"binary": "../spec2017/speckle/build/overlay/intspeed/test/631.deepsjeng_s/deepsjeng_s_base.riscv-64", "asids": [117]} ], - "sbi_binary": "../firemarshal/images/firechip/spec17-intspeed-test-631-631.deepsjeng_s/spec17-intspeed-test-631-631.deepsjeng_s-bin", + "machine_binary": "../firemarshal/images/firechip/spec17-intspeed-test-631-631.deepsjeng_s/spec17-intspeed-test-631-631.deepsjeng_s-bin", "kernel_binary": "../firemarshal/images/firechip/spec17-intspeed-test-631-631.deepsjeng_s/spec17-intspeed-test-631-631.deepsjeng_s-bin-dwarf", "kernel_jump_label_patch_log": "/scratch/iansseijelly/tacit-chipyard/sims/firesim/deploy/results-workload/2025-11-15--01-13-55-spec17-intspeed-test-605/spec17-intspeed-test-605-run-chores/jump_label_patch_map.txt", "driver_binary_entry_tuples": [ ["../firemarshal/boards/firechip/drivers/tacit-driver/tacit.o", "0xffffffff0169d000"], ["../firemarshal/boards/firechip/drivers/iceblk-driver/iceblk.o", "0xffffffff016ac000"] ], - "header_only": false, - "to_stats": false, - "to_txt": false, - "to_stack_txt": false, - "to_atomics": false, - "to_afdo": false, - "gcno": "", - "to_gcda": false, - "to_speedscope": false, - "to_perfetto": false, - "to_foc": false, - "to_vbb": true, - "to_path_profile": false + "receivers": { + "bb_stats": { "enabled": true, "path": "trace.bb_stats.csv", "do_user": true} + } } diff --git a/configs/spec/linux_641_leela.json b/configs/spec/linux_641_leela.json index b8b5a07..46e534a 100644 --- a/configs/spec/linux_641_leela.json +++ b/configs/spec/linux_641_leela.json @@ -1,26 +1,16 @@ { "encoded_trace": "/scratch/iansseijelly/FIRESIM_RUN_TMP/sim_slot_0/tacit0.out", - "application_binary_asid_tuples": [ + "user_binaries": [ ["../spec2017/speckle/build/overlay/intspeed/test/641.leela_s/leela_s_base.riscv-64", "117"] ], - "sbi_binary": "../firemarshal/images/firechip/spec17-intspeed-test-641.leela_s/spec17-intspeed-test-641.leela_s-bin", + "machine_binary": "../firemarshal/images/firechip/spec17-intspeed-test-641.leela_s/spec17-intspeed-test-641.leela_s-bin", "kernel_binary": "../firemarshal/images/firechip/spec17-intspeed-test-641.leela_s/spec17-intspeed-test-641.leela_s-bin-dwarf", "kernel_jump_label_patch_log": "/scratch/iansseijelly/tacit-chipyard/sims/firesim/deploy/results-workload/2025-11-15--01-13-55-spec17-intspeed-test-605/spec17-intspeed-test-605-run-chores/jump_label_patch_map.txt", "driver_binary_entry_tuples": [ ["../firemarshal/boards/firechip/drivers/tacit-driver/tacit.o", "0xffffffff0169d000"], ["../firemarshal/boards/firechip/drivers/iceblk-driver/iceblk.o", "0xffffffff016ac000"] ], - "header_only": false, - "to_stats": false, - "to_txt": false, - "to_stack_txt": false, - "to_atomics": false, - "to_afdo": false, - "gcno": "", - "to_gcda": false, - "to_speedscope": false, - "to_perfetto": false, - "to_foc": false, - "to_vbb": true, - "to_path_profile": false + "receivers": { + "bb_stats": { "enabled": true, "path": "trace.bb_stats.csv", "do_user": true} + } } diff --git a/configs/spec/linux_648_exchange2.json b/configs/spec/linux_648_exchange2.json index 5e7e322..16f557e 100644 --- a/configs/spec/linux_648_exchange2.json +++ b/configs/spec/linux_648_exchange2.json @@ -1,26 +1,16 @@ { "encoded_trace": "/scratch/iansseijelly/FIRESIM_RUN_TMP/sim_slot_0/tacit0.out", - "application_binary_asid_tuples": [ - ["../spec2017/speckle/build/overlay/intspeed/test/648.exchange2_s/exchange2_s_base.riscv-64", "117"] + "user_binaries": [ + {"binary": "../spec2017/speckle/build/overlay/intspeed/test/648.exchange2_s/exchange2_s_base.riscv-64", "asids": [117]} ], - "sbi_binary": "../firemarshal/images/firechip/spec17-intspeed-test-648.exchange2_s/spec17-intspeed-test-648.exchange2_s-bin", + "machine_binary": "../firemarshal/images/firechip/spec17-intspeed-test-648.exchange2_s/spec17-intspeed-test-648.exchange2_s-bin", "kernel_binary": "../firemarshal/images/firechip/spec17-intspeed-test-648.exchange2_s/spec17-intspeed-test-648.exchange2_s-bin-dwarf", "kernel_jump_label_patch_log": "/scratch/iansseijelly/tacit-chipyard/sims/firesim/deploy/results-workload/2025-11-15--01-13-55-spec17-intspeed-test-605/spec17-intspeed-test-605-run-chores/jump_label_patch_map.txt", "driver_binary_entry_tuples": [ ["../firemarshal/boards/firechip/drivers/tacit-driver/tacit.o", "0xffffffff0169d000"], ["../firemarshal/boards/firechip/drivers/iceblk-driver/iceblk.o", "0xffffffff016ac000"] ], - "header_only": false, - "to_stats": false, - "to_txt": false, - "to_stack_txt": false, - "to_atomics": false, - "to_afdo": false, - "gcno": "", - "to_gcda": false, - "to_speedscope": false, - "to_perfetto": false, - "to_foc": false, - "to_vbb": true, - "to_path_profile": false + "receivers": { + "bb_stats": { "enabled": true, "path": "trace.bb_stats.csv", "do_user": true} + } } diff --git a/src/common/insn_index.rs b/src/common/insn_index.rs index 2ea0e10..afafbd5 100644 --- a/src/common/insn_index.rs +++ b/src/common/insn_index.rs @@ -12,7 +12,8 @@ use std::io::{BufRead, BufReader, Read}; use rustc_data_structures::fx::FxHashMap; pub struct InstructionIndex { - u_insn_maps: HashMap>, + asid_to_binary_id_map: HashMap, + u_insn_maps: Vec>, k_insn_map: FxHashMap, m_insn_map: FxHashMap, empty_map: FxHashMap, @@ -22,8 +23,8 @@ impl InstructionIndex { pub fn get(&self, space: Prv, ctx: u64) -> &FxHashMap { match space { Prv::PrvUser => { - if self.u_insn_maps.contains_key(&ctx) { - &self.u_insn_maps[&ctx] + if let Some(binary_id) = self.asid_to_binary_id_map.get(&ctx) { + &self.u_insn_maps[*binary_id] } else { &self.empty_map } @@ -37,7 +38,7 @@ impl InstructionIndex { pub fn build_instruction_index(cfg: DecoderStaticCfg) -> Result { // Machine-space instruction map (SBI) - let mut m_elf_file = File::open(cfg.sbi_binary)?; + let mut m_elf_file = File::open(cfg.machine_binary)?; let mut m_elf_buffer = Vec::new(); m_elf_file.read_to_end(&mut m_elf_buffer)?; let m_elf = object::File::parse(&*m_elf_buffer)?; @@ -67,10 +68,18 @@ pub fn build_instruction_index(cfg: DecoderStaticCfg) -> Result Result()?, u_insn_map); + u_insn_maps.push(u_insn_map); } let mut k_insn_map = FxHashMap::default(); @@ -193,6 +202,7 @@ pub fn build_instruction_index(cfg: DecoderStaticCfg) -> Result, - pub sbi_binary: String, + pub user_binaries: Vec, + pub machine_binary: String, pub kernel_binary: String, pub kernel_jump_label_patch_log: String, pub driver_binary_entry_tuples: Vec<(String, String)>, - pub header_only: bool, - pub to_stats: bool, - pub to_txt: bool, - pub to_stack_txt: bool, - pub to_atomics: bool, - pub to_afdo: bool, - pub gcno: String, - pub to_gcda: bool, - pub to_speedscope: bool, - pub to_perfetto: bool, - pub to_vbb: bool, - pub to_path_profile: bool, + pub receivers: HashMap, } pub fn load_file_config(path: &str) -> Result { @@ -30,3 +20,10 @@ pub fn load_file_config(path: &str) -> Result { let cfg: DecoderStaticCfg = serde_json::from_reader(reader)?; Ok(cfg) } + +#[derive(Debug, Clone, Serialize, Deserialize, Default)] +#[serde(default)] +pub struct UserBinaryCfg { + pub binary: String, + pub asids: Vec, +} \ No newline at end of file diff --git a/src/common/symbol_index.rs b/src/common/symbol_index.rs index 1bcb1d3..1ae77ed 100644 --- a/src/common/symbol_index.rs +++ b/src/common/symbol_index.rs @@ -16,12 +16,12 @@ pub struct SymbolInfo { pub name: String, pub src: SourceLocation, pub prv: Prv, - pub ctx: u64, } pub struct SymbolIndex { // use BTreeMap as symbol maps need to be ordered - u_symbol_map: HashMap>, + asid_to_binary_id_map: HashMap, + u_symbol_maps: Vec>, k_symbol_map: BTreeMap, m_symbol_map: BTreeMap, } @@ -29,15 +29,21 @@ pub struct SymbolIndex { impl SymbolIndex { pub fn get(&self, prv: Prv, ctx: u64) -> &BTreeMap { match prv { - Prv::PrvUser => &self.u_symbol_map[&ctx], + Prv::PrvUser => { + if let Some(binary_id) = self.asid_to_binary_id_map.get(&ctx) { + &self.u_symbol_maps[*binary_id] + } else { + panic!("Context {} not found in symbol index", ctx); + } + } Prv::PrvSupervisor => &self.k_symbol_map, Prv::PrvMachine => &self.m_symbol_map, _ => panic!("Unsupported privilege level: {:?}", prv), } } - pub fn get_user_symbol_map(&self) -> &HashMap> { - &self.u_symbol_map + pub fn get_user_symbol_map(&self) -> &Vec> { + &self.u_symbol_maps } pub fn get_kernel_symbol_map(&self) -> &BTreeMap { @@ -48,6 +54,10 @@ impl SymbolIndex { &self.m_symbol_map } + pub fn get_asid_to_binary_id_map(&self) -> &HashMap { + &self.asid_to_binary_id_map + } + /// Return the half-open address range `[start, end)` for the function that /// begins at `addr`. The end is the start of the next symbol in that /// privilege space, or `u64::MAX` if this is the last symbol. @@ -75,7 +85,6 @@ pub fn build_single_symbol_index( elf_path: String, prv: Prv, offset: u64, - ctx: u64, ) -> Result> { // open application elf for symbol processing let elf_data = fs::read(&elf_path)?; @@ -116,7 +125,6 @@ pub fn build_single_symbol_index( prv: prv, }, prv: prv, - ctx: ctx, }; if let Ok(Some(loc)) = loc { let src: SourceLocation = SourceLocation::from_addr2line(loc, prv); @@ -145,34 +153,40 @@ pub fn build_single_symbol_index( } pub fn build_symbol_index(cfg: DecoderStaticCfg) -> Result { - let mut u_symbol_maps = HashMap::new(); - for (binary, asid) in cfg.application_binary_asid_tuples.clone() { + // Build a asid to binary id map + let mut asid_to_binary_id_map = HashMap::new(); + for (i, user_binary) in cfg.user_binaries.iter().enumerate() { + for asid in user_binary.asids.clone() { + asid_to_binary_id_map.insert(asid, i); + } + } + let mut u_symbol_maps = Vec::new(); + for user_binary in cfg.user_binaries.iter() { let u_func_symbol_map = - build_single_symbol_index(binary.clone(), Prv::PrvUser, 0, asid.parse::()?)?; - u_symbol_maps.insert(asid.parse::()?, u_func_symbol_map); + build_single_symbol_index(user_binary.binary.clone(), Prv::PrvUser, 0)?; + u_symbol_maps.push(u_func_symbol_map); debug!("u_symbol_maps size: {}", u_symbol_maps.len()); } let mut k_func_symbol_map = BTreeMap::new(); if cfg.kernel_binary != "" { k_func_symbol_map = - build_single_symbol_index(cfg.kernel_binary.clone(), Prv::PrvSupervisor, 0, 0)?; + build_single_symbol_index(cfg.kernel_binary.clone(), Prv::PrvSupervisor, 0)?; debug!("k_func_symbol_map size: {}", k_func_symbol_map.len()); for (binary, entry) in cfg.driver_binary_entry_tuples { let driver_entry_point = u64::from_str_radix(entry.trim_start_matches("0x"), 16)?; let func_symbol_map = build_single_symbol_index( binary.clone(), Prv::PrvSupervisor, - driver_entry_point, - 0, - )?; + driver_entry_point)?; k_func_symbol_map.extend(func_symbol_map); debug!("k_func_symbol_map size: {}", k_func_symbol_map.len()); } } let m_func_symbol_map = - build_single_symbol_index(cfg.sbi_binary.clone(), Prv::PrvMachine, 0, 0)?; + build_single_symbol_index(cfg.machine_binary.clone(), Prv::PrvMachine, 0)?; Ok(SymbolIndex { - u_symbol_map: u_symbol_maps, + asid_to_binary_id_map, + u_symbol_maps, k_symbol_map: k_func_symbol_map, m_symbol_map: m_func_symbol_map, }) diff --git a/src/frontend/decoder.rs b/src/frontend/decoder.rs index ebf0b15..66fbddc 100644 --- a/src/frontend/decoder.rs +++ b/src/frontend/decoder.rs @@ -20,6 +20,7 @@ use crate::frontend::decoder_cache::{BasicBlockStats, DecoderCache}; use rustc_data_structures::fx::FxHashMap; use rvdasm::insn::Insn; use std::sync::Arc; +use std::collections::HashSet; // const ADDR_BITS: u64 = 64; const ADDR_BITS: u64 = 40; @@ -159,13 +160,8 @@ fn step_bb_until( pc } -fn find_ctx(ctx: u64, static_cfg: &DecoderStaticCfg) -> bool { - for (_, asid) in static_cfg.application_binary_asid_tuples.iter() { - if asid.parse::().unwrap() == ctx { - return true; - } - } - false +fn find_ctx(ctx: u64, valid_ctxs: &HashSet) -> bool { + valid_ctxs.contains(&ctx) } pub fn decode_trace( @@ -195,6 +191,14 @@ pub fn decode_trace( let mode_is_predict = br_mode == BrMode::BrPredict; let mut bp_counter = BpDoubleSaturatingCounter::new(runtime_cfg.bp_entries); + // Build a set of what ctx is valid + let mut valid_ctxs = HashSet::new(); + for user_binary in static_cfg.user_binaries.iter() { + for asid in user_binary.asids.iter() { + valid_ctxs.insert(*asid); + } + } + // initial state from first packet // let mut packet_count = 0u64; let mut pc = PC::new(first_packet.target_address); @@ -286,7 +290,7 @@ pub fn decode_trace( trace!("new set pc: {:x}", pc.get_addr()); curr_insn_map = get_insn_map(prv, ctx); // update the instruction map if report_ctx { - if find_ctx(packet.target_ctx, &static_cfg) { + if find_ctx(packet.target_ctx, &valid_ctxs) { if ctx != packet.target_ctx { decoder_cache.reset(); } diff --git a/src/main.rs b/src/main.rs index c0af1a1..e804ee1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -88,21 +88,22 @@ fn main() -> Result<()> { }; // verify the binary exists and is a file - for (binary, _) in static_cfg.application_binary_asid_tuples.clone() { - if !Path::new(&binary).exists() || !Path::new(&binary).is_file() { + for user_binary in static_cfg.user_binaries.clone() { + let binary_path = user_binary.binary; + if !Path::new(&binary_path).exists() || !Path::new(&binary_path).is_file() { return Err(anyhow::anyhow!( "Application binary file is not valid: {}", - binary + binary_path )); } } - if static_cfg.sbi_binary != "" - && (!Path::new(&static_cfg.sbi_binary).exists() - || !Path::new(&static_cfg.sbi_binary).is_file()) + if static_cfg.machine_binary != "" + && (!Path::new(&static_cfg.machine_binary).exists() + || !Path::new(&static_cfg.machine_binary).is_file()) { return Err(anyhow::anyhow!( "SBI binary file is not valid: {}", - static_cfg.sbi_binary + static_cfg.machine_binary )); } if static_cfg.kernel_binary != "" @@ -133,7 +134,7 @@ fn main() -> Result<()> { (first_packet, runtime_cfg) }; - if static_cfg.header_only { + if args.header_only.unwrap_or(false) { println!("Printing header configuration: {:?}", runtime_cfg); println!("Printing first packet: {:?}", first_packet); println!( @@ -155,41 +156,28 @@ fn main() -> Result<()> { if let Some(path) = &args.dump_symbol_index { let mut f = std::fs::File::create(path)?; - for (asid, symbol_map) in symbol_index.get_user_symbol_map().iter() { + for symbol_map in symbol_index.get_user_symbol_map().iter() { for (addr, symbol) in symbol_map.iter() { - writeln!(f, "{} 0x{:x} {}", symbol.name, addr, asid).unwrap(); + writeln!(f, "{} 0x{:x}", symbol.name, addr).unwrap(); } } for (addr, symbol) in symbol_index.get_kernel_symbol_map().iter() { - writeln!(f, "{} 0x{:x} {}", symbol.name, addr, 0).unwrap(); + writeln!(f, "{} 0x{:x}", symbol.name, addr).unwrap(); } for (addr, symbol) in symbol_index.get_machine_symbol_map().iter() { - writeln!(f, "{} 0x{:x} {}", symbol.name, addr, 0).unwrap(); + writeln!(f, "{} 0x{:x}", symbol.name, addr).unwrap(); } } let mut bus: Bus = Bus::new(BUS_SIZE); let mut receivers: Vec> = vec![]; - let receiver_cfg = if let Some(path) = &args.config { - let f = File::open(path)?; - let reader = BufReader::new(f); - let value: serde_json::Value = serde_json::from_reader(reader)?; - value - .get("receivers") - .cloned() - .unwrap_or_else(|| serde_json::Value::Null) - } else { - serde_json::Value::Null - }; + let receiver_cfg = static_cfg.receivers.clone(); - if !receiver_cfg.is_null() { - let shared = receivers::abstract_receiver::Shared::new(&static_cfg, &runtime_cfg)?; + if !receiver_cfg.is_empty() { + let shared = receivers::abstract_receiver::Shared::new(&static_cfg.clone(), &runtime_cfg.clone())?; - let receiver_map = receiver_cfg.as_object().ok_or_else(|| { - anyhow::anyhow!("receivers config must be an object map of name -> config") - })?; - for (name, cfg) in receiver_map { + for (name, cfg) in receiver_cfg.iter() { let enabled = cfg .get("enabled") .and_then(|value| value.as_bool()) diff --git a/src/receivers/speedscope_receiver.rs b/src/receivers/speedscope_receiver.rs index ee6d614..0fd59bd 100644 --- a/src/receivers/speedscope_receiver.rs +++ b/src/receivers/speedscope_receiver.rs @@ -21,19 +21,23 @@ struct ProfileEvent { } struct Lookup { - u_lookup: HashMap>, + asid_to_binary_id_map: HashMap, + u_lookup: Vec>, k_lookup: HashMap, m_lookup: HashMap, + asid_lookup: HashMap, } impl Lookup { fn lookup(&self, prv: Prv, ctx: u64, addr: u64) -> Option { match prv { - Prv::PrvUser => self - .u_lookup - .get(&ctx) - .and_then(|lookup| lookup.get(&addr)) - .copied(), + Prv::PrvUser => { + if let Some(binary_id) = self.asid_to_binary_id_map.get(&ctx) { + self.u_lookup[*binary_id].get(&addr).copied() + } else { + None + } + } Prv::PrvSupervisor => self.k_lookup.get(&addr).copied(), Prv::PrvMachine => self.m_lookup.get(&addr).copied(), _ => panic!("Unsupported privilege level: {:?}", prv), @@ -50,6 +54,7 @@ pub struct SpeedscopeReceiver { end: u64, events: Vec, unwinder: StackUnwinder, + curr_ctx: u64, } impl SpeedscopeReceiver { @@ -78,6 +83,7 @@ impl SpeedscopeReceiver { end: 0, events: Vec::new(), unwinder, + curr_ctx: 0, } } } @@ -123,9 +129,25 @@ impl SpeedscopeReceiver { fn lookup_frame(&self, frame: &Frame) -> Option { let id = self .frame_lookup - .lookup(frame.symbol.prv, frame.symbol.ctx, frame.addr); + .lookup(frame.prv, frame.ctx, frame.addr); id } + + fn update_asid_frame(&mut self, ts: u64, ctx: u64) { + if ctx == self.curr_ctx { + return; + } + if self.curr_ctx != 0 { + if let Some(id) = self.frame_lookup.asid_lookup.get(&self.curr_ctx) { + self.events.push(ProfileEvent { kind: "C".into(), frame: *id, at: ts }); + } + } + if let Some(id) = self.frame_lookup.asid_lookup.get(&ctx) { + self.events.push(ProfileEvent { kind: "O".into(), frame: *id, at: ts }); + } + self.curr_ctx = ctx; + } + } impl AbstractReceiver for SpeedscopeReceiver { @@ -141,26 +163,39 @@ impl AbstractReceiver for SpeedscopeReceiver { match entry { Entry::Instruction { .. } => {} Entry::Event { timestamp, kind } => { + if let Some(update) = self.unwinder.step(&Entry::Event { + timestamp, + kind: kind.clone(), + }) { + self.record_stack_update(timestamp, update); + } + match &kind { EventKind::SyncStart { start_prv: _, start_pc: _, + start_ctx, .. } => { self.start = timestamp; + self.update_asid_frame(timestamp, *start_ctx); + self.curr_ctx = *start_ctx; } EventKind::SyncEnd { .. } => { self.end = timestamp; } + EventKind::Trap { + reason: _, + prv_arc, + arc: _, + ctx, + } => { + if prv_arc.1 == Prv::PrvUser { + self.update_asid_frame(timestamp, ctx.unwrap()); + } + } _ => {} } - - if let Some(update) = self.unwinder.step(&Entry::Event { - timestamp, - kind: kind.clone(), - }) { - self.record_stack_update(timestamp, update); - } } } } @@ -185,6 +220,10 @@ impl AbstractReceiver for SpeedscopeReceiver { } } + if let Some(id) = self.frame_lookup.asid_lookup.get(&self.curr_ctx) { + self.events.push(ProfileEvent { kind: "C".into(), frame: *id, at: self.end }); + } + write_speedscope( &mut self.writer, &self.frames, @@ -201,7 +240,10 @@ impl AbstractReceiver for SpeedscopeReceiver { /// Build Speedscope frames and an address→frame-id lookup. fn build_frames(symbols: &SymbolIndex) -> (Vec, Lookup) { let mut frames = Vec::new(); - let mut u_lookups: HashMap> = HashMap::new(); + + // Build a asid to binary id map + let asid_to_binary_id_map = symbols.get_asid_to_binary_id_map().clone(); + let mut u_lookups: Vec> = Vec::new(); let mut k_lookup: HashMap = HashMap::new(); let mut m_lookup: HashMap = HashMap::new(); @@ -225,24 +267,38 @@ fn build_frames(symbols: &SymbolIndex) -> (Vec, Lookup) { m_lookup.insert(addr, id); } // iterate over the user space symbol map - for (&asid, user_symbol_map) in symbols.get_user_symbol_map().iter() { + for user_symbol_map in symbols.get_user_symbol_map().iter() { let mut u_lookup: HashMap = HashMap::new(); for (&addr, info) in user_symbol_map.iter() { let id = frames.len() as u32; frames.push(json!({ - "name": format!("{}:{}", asid, info.name), + "name": format!("{}", info.name), "file": info.src.file, "line": info.src.lines, })); u_lookup.insert(addr, id); } - u_lookups.insert(asid, u_lookup); + u_lookups.push(u_lookup); + } + + // build a fake asid frame for each user asid + let mut asid_lookup = HashMap::new(); + for asid in asid_to_binary_id_map.keys() { + let id = frames.len() as u32; + frames.push(json!({ + "name": format!("u_{}", asid), + "file": "unknown", + "line": 0, + })); + asid_lookup.insert(*asid, id); } let lookup = Lookup { + asid_to_binary_id_map, u_lookup: u_lookups, k_lookup: k_lookup, m_lookup: m_lookup, + asid_lookup: asid_lookup, }; (frames, lookup) diff --git a/src/receivers/stack_unwinder.rs b/src/receivers/stack_unwinder.rs index 0720c66..331f8a5 100644 --- a/src/receivers/stack_unwinder.rs +++ b/src/receivers/stack_unwinder.rs @@ -10,6 +10,8 @@ use crate::common::symbol_index::{SymbolIndex, SymbolInfo}; pub struct Frame { pub symbol: SymbolInfo, pub addr: u64, + pub ctx: u64, + pub prv: Prv, } pub struct StackUnwinder { @@ -46,6 +48,8 @@ impl StackUnwinder { let frame = Frame { symbol: symbol.clone(), addr: *start, + ctx: ctx, + prv: prv, }; self.frame_stack.push(frame.clone()); Some(frame) From 3b9392b0785fc66125d162d813582711d47c1e47 Mon Sep 17 00:00:00 2001 From: Lux Date: Sun, 22 Feb 2026 18:01:21 -0800 Subject: [PATCH 09/24] stage: a tc emulation receiver --- src/receivers/tc_emulation_receiver.rs | 89 ++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 src/receivers/tc_emulation_receiver.rs diff --git a/src/receivers/tc_emulation_receiver.rs b/src/receivers/tc_emulation_receiver.rs new file mode 100644 index 0000000..85368b8 --- /dev/null +++ b/src/receivers/tc_emulation_receiver.rs @@ -0,0 +1,89 @@ +use crate::receivers::abstract_receiver::{AbstractReceiver, BusReceiver, Shared}; +use crate::backend::event::{Entry, EventKind}; +use bus::BusReader; +use std::fs::File; +use std::io::{BufWriter, Write}; + +pub struct TcEmulationReceiver { + writer: BufWriter, + receiver: BusReceiver, + curr_tc: u64, + interval: u64, + event_staging: Vec, +} + +/* Emulates the behavior of a TC-based encoder, used for accuracy analysis + A TC-based encoder encodes timestamp as separate packets emitted in fixed intervals. +*/ +impl TcEmulationReceiver { + pub fn new(bus_rx: BusReader, path: String, interval: u64) -> Self { + Self { + writer: BufWriter::new(File::create(path).unwrap()), + receiver: BusReceiver { + name: "tc_emulation".to_string(), + bus_rx: bus_rx, + checksum: 0, + }, + curr_tc: 0, + interval: interval, + event_staging: Vec::new(), + } + } +} + +pub fn factory( + _shared: &Shared, + _config: serde_json::Value, + bus_rx: BusReader, +) -> Box { + let path = _config.get("path").and_then(|value| value.as_str()).unwrap_or("trace.tc_emulation.txt").to_string(); + let interval = _config.get("interval").and_then(|value| value.as_u64()).unwrap_or(1000000); + Box::new(TcEmulationReceiver::new(bus_rx, path, interval)) +} + +crate::register_receiver!("tc_emulation", factory); + +impl AbstractReceiver for TcEmulationReceiver { + fn bus_rx(&mut self) -> &mut BusReader { + &mut self.receiver.bus_rx + } + + fn _bump_checksum(&mut self) { + self.receiver.checksum += 1; + } + + fn _receive_entry(&mut self, entry: Entry) { + match entry { + Entry::Event { timestamp, kind: EventKind::SyncStart { .. } } => { + self.curr_tc = timestamp / self.interval; + } + Entry::Event { timestamp, kind } => { + if timestamp / self.interval != self.curr_tc { + // smear the timestamps distributing across all events staged, excluding the current event + let slack = (timestamp / self.interval - self.curr_tc) * self.interval; + let num_events = self.event_staging.len() as u64; + let delta_tc = slack / num_events; + for event in self.event_staging.iter() { + self.writer + .write_all(format!("[timestamp delta: {}]",delta_tc).as_bytes()) + .unwrap(); + self.writer + .write_all(format!(" {}", event).as_bytes()) + .unwrap(); + self.writer.write_all(b"\n").unwrap(); + } + // clear the staged events + self.event_staging.clear(); + // update the current TC + self.curr_tc = timestamp / self.interval; + } + self.event_staging.push(kind); + } + _ => {} + } + } + + fn _flush(&mut self) { + self.writer.flush().unwrap(); + } +} From b96762c2ce210006a6b4bc23430a1b903f20a662 Mon Sep 17 00:00:00 2001 From: Lux Date: Sun, 22 Feb 2026 18:01:37 -0800 Subject: [PATCH 10/24] add: mod tc emulation receiver --- src/receivers/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/receivers/mod.rs b/src/receivers/mod.rs index 51f0415..92f2a66 100644 --- a/src/receivers/mod.rs +++ b/src/receivers/mod.rs @@ -8,6 +8,7 @@ pub mod speedscope_receiver; pub mod stack_txt_receiver; pub mod bb_stats_receiver; pub mod path_profile_receiver; +pub mod tc_emulation_receiver; // TODO: mask off for now until verified again // pub mod afdo_receiver; From f0ecc5d470e23a3a238a1dfbe74f481c28087ab7 Mon Sep 17 00:00:00 2001 From: Lux Date: Sun, 22 Feb 2026 18:01:54 -0800 Subject: [PATCH 11/24] add: a little error handler for failed symbol index loading --- src/common/symbol_index.rs | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/common/symbol_index.rs b/src/common/symbol_index.rs index 1ae77ed..122cd93 100644 --- a/src/common/symbol_index.rs +++ b/src/common/symbol_index.rs @@ -90,8 +90,15 @@ pub fn build_single_symbol_index( let elf_data = fs::read(&elf_path)?; let obj_file = object::File::parse(&*elf_data)?; debug!("elf_path: {}", elf_path); - let loader = Loader::new(&elf_path) - .map_err(|e| anyhow::Error::msg("loader error: ".to_string() + &e.to_string()))?; + let loader = match Loader::new(&elf_path) { + Ok(loader) => Some(loader), + Err(e) => { + // Some DWARF encodings (e.g., newer range list formats) can trip up + // addr2line/gimli. We still want symbols, just without source info. + warn!("DWARF loader error for {}: {}", elf_path, e); + None + } + }; // Gather indices of all executable sections let exec_secs: std::collections::HashSet<_> = obj_file @@ -116,7 +123,7 @@ pub fn build_single_symbol_index( if !name.starts_with("$x") && !name.starts_with("$d") && !name.starts_with(".L") { let addr = symbol.address(); // lookup source location (may return None) - let loc = loader.find_location(addr); + let loc = loader.as_ref().map(|l| l.find_location(addr)); let mut info: SymbolInfo = SymbolInfo { name: name.to_string(), src: SourceLocation { @@ -126,9 +133,11 @@ pub fn build_single_symbol_index( }, prv: prv, }; - if let Ok(Some(loc)) = loc { - let src: SourceLocation = SourceLocation::from_addr2line(loc, prv); - info.src = src; + if let Some(loc) = loc { + if let Ok(Some(loc)) = loc { + let src: SourceLocation = SourceLocation::from_addr2line(loc, prv); + info.src = src; + } } // dedupe aliases: prefer non‑empty over empty if let Some(existing) = func_symbol_map.get_mut(&addr) { From b14e668dc8d8f825a2af1181d5c58d49a8a5e473 Mon Sep 17 00:00:00 2001 From: Lux Date: Sun, 22 Feb 2026 18:02:20 -0800 Subject: [PATCH 12/24] add: updated the linux process lifecycle benchmark config, formatted json --- configs/linux/linux_process_launch.json | 97 ++++++++++++++++++++----- 1 file changed, 78 insertions(+), 19 deletions(-) diff --git a/configs/linux/linux_process_launch.json b/configs/linux/linux_process_launch.json index aaba70a..45d8333 100644 --- a/configs/linux/linux_process_launch.json +++ b/configs/linux/linux_process_launch.json @@ -1,20 +1,79 @@ { - "encoded_trace": "/scratch/iansseijelly/FIRESIM_RUN_TMP/sim_slot_1/tacit0.out", - "user_binaries": [ - {"binary": "../firemarshal/example-workloads/process-launch/overlay/root/process-launch/trace-submit", "asids": [106]}, - {"binary": "../firemarshal/example-workloads/process-launch/overlay/root/process-launch/dummy", "asids": [677, 678, 679, 680, 681, 682, 683, 684]} - ], - "machine_binary": "../firemarshal/images/firechip/process-launch/process-launch-bin", - "kernel_binary": "../firemarshal/images/firechip/process-launch/process-launch-bin-dwarf", - "kernel_jump_label_patch_log": "/scratch/iansseijelly/tacit-chipyard/sims/firesim/deploy/results-workload/2026-01-28--19-09-05-process-launch/process-launch-run-chores/jump_label_patch_map.txt", - "driver_binary_entry_tuples": [ - ["../firemarshal/images/firechip/process-launch/tacit-dwarf", "0xffffffff0169d000"], - ["../firemarshal/images/firechip/process-launch/iceblk-dwarf", "0xffffffff016ac000"] - ], - "receivers": { - "txt": { "enabled": false, "path": "trace.test.txt" }, - "prv_breakdown": { "enabled": true }, - "speedscope": { "enabled": true, "path": "trace.speedscope.json" }, - "bb_stats": { "enabled": false, "path": "trace.bb_stats.csv", "do_supervisor": true} - } -} + "encoded_trace": "/scratch/iansseijelly/FIRESIM_RUN_TMP/sim_slot_1/tacit0.out", + "user_binaries": [ + { + "binary": "../firemarshal/example-workloads/process-launch/overlay/root/process-launch/trace-submit", + "asids": [ + 106 + ] + }, + { + "binary": "../firemarshal/example-workloads/process-launch/overlay/root/process-launch/dummy", + "asids": [ + 1077, + 1078, + 1079, + 1080, + 1081, + 1082, + 1083, + 1084, + 1085, + 1086, + 1087, + 1088, + 1089, + 1090, + 1091, + 1092, + 1093, + 1094, + 1095, + 1096, + 1097, + 1098, + 1099, + 1100, + 1101, + 1102, + 1103, + 1104, + 1105, + 1106, + 1107, + 1108 + ] + } + ], + "machine_binary": "../firemarshal/images/firechip/process-launch/process-launch-bin", + "kernel_binary": "../firemarshal/images/firechip/process-launch/process-launch-bin-dwarf", + "kernel_jump_label_patch_log": "/scratch/iansseijelly/tacit-chipyard/sims/firesim/deploy/results-workload/2026-02-18--00-01-56-trace-hello/trace-hello-run-chores/jump_label_patch_map.txt", + "driver_binary_entry_tuples": [ + [ + "../firemarshal/images/firechip/process-launch/tacit-dwarf", + "0xffffffff01b08000" + ], + [ + "../firemarshal/images/firechip/process-launch/iceblk-dwarf", + "0xffffffff01b6b000" + ] + ], + "receivers": { + "txt": { + "enabled": true, + "path": "trace.test.txt" + }, + "prv_breakdown": { + "enabled": true + }, + "speedscope": { + "enabled": true, + "path": "trace.speedscope.json" + }, + "bb_stats": { + "enabled": false, + "path": "trace.bb_stats.csv", + "do_supervisor": true + } + } +} \ No newline at end of file From 7eb0ed96708c734fdd6e0334fce5eb6d206b28cb Mon Sep 17 00:00:00 2001 From: Lux Date: Sun, 22 Feb 2026 18:02:35 -0800 Subject: [PATCH 13/24] refactor: reorganized the script directory for tidyness --- scripts/{ => analysis}/draw_bb.py | 0 scripts/analysis/plot_distribution.py | 53 +++ scripts/{ => analysis}/plot_foc.py | 0 scripts/{ => analysis}/sort_bb.py | 0 scripts/{ => analysis}/sort_path.py | 0 scripts/config/batch_asid_json.py | 22 ++ scripts/config/sort_asid.py | 38 +++ scripts/decode_one.py | 466 -------------------------- scripts/filter_bp.py | 12 - scripts/find_divergence_spike.py | 74 ---- scripts/find_divergence_verilator.py | 124 ------- scripts/match_joints.py | 68 ---- scripts/plot_distribution.py | 33 -- 13 files changed, 113 insertions(+), 777 deletions(-) rename scripts/{ => analysis}/draw_bb.py (100%) create mode 100644 scripts/analysis/plot_distribution.py rename scripts/{ => analysis}/plot_foc.py (100%) rename scripts/{ => analysis}/sort_bb.py (100%) rename scripts/{ => analysis}/sort_path.py (100%) create mode 100644 scripts/config/batch_asid_json.py create mode 100644 scripts/config/sort_asid.py delete mode 100755 scripts/decode_one.py delete mode 100644 scripts/filter_bp.py delete mode 100644 scripts/find_divergence_spike.py delete mode 100644 scripts/find_divergence_verilator.py delete mode 100644 scripts/match_joints.py delete mode 100644 scripts/plot_distribution.py diff --git a/scripts/draw_bb.py b/scripts/analysis/draw_bb.py similarity index 100% rename from scripts/draw_bb.py rename to scripts/analysis/draw_bb.py diff --git a/scripts/analysis/plot_distribution.py b/scripts/analysis/plot_distribution.py new file mode 100644 index 0000000..55622f3 --- /dev/null +++ b/scripts/analysis/plot_distribution.py @@ -0,0 +1,53 @@ +# Given a sequence of iter: time pairs, plot the distribution of the times. + +import matplotlib.pyplot as plt +import numpy as np +import pandas as pd +import argparse +import re + +pattern = r'(\d+): (\d+)' + +def _sci_fmt(x: float) -> str: + s = f'{x:.2e}' + return s + +def plot_distribution(input_file: str) -> None: + with open(input_file, 'r') as f: + content = f.read() + matches = re.findall(pattern, content) + times = [int(match[1]) for match in matches] + plt.hist(times, bins=100, alpha=0.8, weights=np.ones_like(times) / len(times) * 100) + + mean_val = sum(times) / len(times) + p90 = np.percentile(times, 90) + p95 = np.percentile(times, 95) + p99 = np.percentile(times, 99) + + plt.axvline(mean_val, color='green', linestyle='--', linewidth=1, label=f'p50 ({_sci_fmt(mean_val)})') + plt.axvline(p90, color='orange', linestyle='--', linewidth=1, label=f'p90 ({_sci_fmt(p90)})') + plt.axvline(p95, color='red', linestyle='--', linewidth=1, label=f'p95 ({_sci_fmt(p95)})') + plt.axvline(p99, color='darkviolet', linestyle='--', linewidth=1, label=f'p99 ({_sci_fmt(p99)})') + plt.legend() + plt.xlabel('Latency (cycles)') + plt.ylabel('Percentage (%)') + + plt.title(f'Distribution for process spawn-reap latency') + plt.tight_layout() + + print(f'{input_file}: {min(times)} to {max(times)}') + print(f'{input_file}: {mean_val} average') + print(f'{input_file}: {np.median(times)} median') + print(f'{input_file}: {np.percentile(times, 25)} 25th percentile') + print(f'{input_file}: {np.percentile(times, 75)} 75th percentile') + print(f'{input_file}: {p90} 90th percentile') + print(f'{input_file}: {p95} 95th percentile') + print(f'{input_file}: {p99} 99th percentile') + + plt.savefig(f'{input_file}.png') + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument('--input', type=str, required=True) + args = parser.parse_args() + plot_distribution(args.input) \ No newline at end of file diff --git a/scripts/plot_foc.py b/scripts/analysis/plot_foc.py similarity index 100% rename from scripts/plot_foc.py rename to scripts/analysis/plot_foc.py diff --git a/scripts/sort_bb.py b/scripts/analysis/sort_bb.py similarity index 100% rename from scripts/sort_bb.py rename to scripts/analysis/sort_bb.py diff --git a/scripts/sort_path.py b/scripts/analysis/sort_path.py similarity index 100% rename from scripts/sort_path.py rename to scripts/analysis/sort_path.py diff --git a/scripts/config/batch_asid_json.py b/scripts/config/batch_asid_json.py new file mode 100644 index 0000000..112d19e --- /dev/null +++ b/scripts/config/batch_asid_json.py @@ -0,0 +1,22 @@ +import json +import argparse + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("--config", type=str, required=True) # the file to touch + parser.add_argument("--binary", type=str, required=True) # the binary name to modify + parser.add_argument("--asid_range", type=str, required=True) # the ASID range to add + args = parser.parse_args() + + with open(args.config, "r") as f: + config = json.load(f) + + # modify the config + start, end = args.asid_range.split("-") + for user_binary in config["user_binaries"]: + if user_binary["binary"] == args.binary: + user_binary["asids"] = list(range(int(start), int(end))) + break + + with open(args.config, "w") as f: + json.dump(config, f, indent=4) \ No newline at end of file diff --git a/scripts/config/sort_asid.py b/scripts/config/sort_asid.py new file mode 100644 index 0000000..bd6b09f --- /dev/null +++ b/scripts/config/sort_asid.py @@ -0,0 +1,38 @@ +import argparse +import re +from collections import defaultdict + +def parse_args(): + parser = argparse.ArgumentParser( + description="Summarize min/max ASID per comm from a log file." + ) + parser.add_argument( + "input", + type=str, + help="Path to the input log file", + ) + return parser.parse_args() + + +def main(): + args = parse_args() + + pattern = re.compile(r"\basid=(\d+)\b.*\bcomm=([^\s]+)") + stats = defaultdict(list) + + with open(args.input, "r") as f: + for line in f: + m = pattern.search(line) + if not m: + continue + asid = int(m.group(1)) + comm = m.group(2) + stats[comm].append(asid) + + for comm in sorted(stats.keys()): + values = stats[comm] + print(f"{comm} {min(values)} {max(values)}") + + +if __name__ == "__main__": + main() diff --git a/scripts/decode_one.py b/scripts/decode_one.py deleted file mode 100755 index 8e3b536..0000000 --- a/scripts/decode_one.py +++ /dev/null @@ -1,466 +0,0 @@ -#!/usr/bin/env python3 -""" -Decode a single packet from a trace stream. -Usage: python3 decode_one.py [additional_bytes...] -""" - -import sys -from typing import Tuple, List - - -# Constants from Rust code -C_HEADER_MASK = 0b0000_0011 -C_TIMESTAMP_MASK = 0b1111_1100 -F_HEADER_MASK = 0b0001_1100 -FHEADER_OFFSET = 2 -SYNC_TYPE_MASK = 0b1110_0000 -SYNC_TYPE_OFFSET = 5 -TRAP_TYPE_MASK = 0b1110_0000 -TRAP_TYPE_OFFSET = 5 -BP_MODE_MASK = 0b11 -BP_ENTRY_MASK = 0b1111_1100 -BP_ENTRY_OFFSET = 2 -BP_BASE_VALUE = 64 - -VAR_MASK = 0b1000_0000 -VAR_LAST = 0b1000_0000 -VAR_OFFSET = 7 -VAR_VAL_MASK = 0b0111_1111 - - -class CHeader: - CTb = 0b00 # taken branch - CNt = 0b01 # not taken branch - CNa = 0b10 # not applicable - CIj = 0b11 # inferable jump - - @staticmethod - def to_string(value: int) -> str: - if value == CHeader.CTb: - return "CTb (taken branch)" - elif value == CHeader.CNt: - return "CNt (not taken branch)" - elif value == CHeader.CNa: - return "CNa (not applicable)" - elif value == CHeader.CIj: - return "CIj (inferable jump)" - else: - return f"Unknown CHeader ({value:02b})" - - -class FHeader: - FTb = 0b000 # taken branch - FNt = 0b001 # non taken branch - FUj = 0b010 # uninferable jump - FIj = 0b011 # inferable jump - FTrap = 0b100 # trapping happened - FSync = 0b101 # synchronization packet - FRes1 = 0b110 # context change - FRes2 = 0b111 # reserved - - @staticmethod - def to_string(value: int) -> str: - names = { - FHeader.FTb: "FTb (taken branch)", - FHeader.FNt: "FNt (not taken branch)", - FHeader.FUj: "FUj (uninferable jump)", - FHeader.FIj: "FIj (inferable jump)", - FHeader.FTrap: "FTrap (trap/interrupt/exception)", - FHeader.FSync: "FSync (synchronization)", - FHeader.FRes1: "FRes1 (context change)", - FHeader.FRes2: "FRes2 (reserved)", - } - return names.get(value, f"Unknown FHeader ({value:03b})") - - -class SyncType: - SyncNone = 0b000 - SyncStart = 0b001 - SyncPeriodic = 0b010 - SyncEnd = 0b011 - - @staticmethod - def to_string(value: int) -> str: - names = { - SyncType.SyncNone: "SyncNone", - SyncType.SyncStart: "SyncStart", - SyncType.SyncPeriodic: "SyncPeriodic", - SyncType.SyncEnd: "SyncEnd", - } - return names.get(value, f"Unknown SyncType ({value:03b})") - - -class TrapType: - TNone = 0b000 - TException = 0b001 - TInterrupt = 0b010 - TReturn = 0b100 - - @staticmethod - def to_string(value: int) -> str: - names = { - TrapType.TNone: "TNone", - TrapType.TException: "TException", - TrapType.TInterrupt: "TInterrupt", - TrapType.TReturn: "TReturn", - } - return names.get(value, f"Unknown TrapType ({value:03b})") - - -class Prv: - PrvUser = 0b000 - PrvSupervisor = 0b001 - PrvHypervisor = 0b010 - PrvMachine = 0b011 - - @staticmethod - def to_string(value: int) -> str: - names = { - Prv.PrvUser: "User", - Prv.PrvSupervisor: "Supervisor", - Prv.PrvHypervisor: "Hypervisor", - Prv.PrvMachine: "Machine", - } - return names.get(value, f"Unknown Prv ({value:03b})") - - -class BrMode: - BrTarget = 0b00 - BrHistory = 0b01 - BrPredict = 0b10 - BrReserved = 0b11 - - @staticmethod - def to_string(value: int) -> str: - names = { - BrMode.BrTarget: "BrTarget", - BrMode.BrHistory: "BrHistory", - BrMode.BrPredict: "BrPredict", - BrMode.BrReserved: "BrReserved", - } - return names.get(value, f"Unknown BrMode ({value:02b})") - - -def read_varint(data: List[int], offset: int) -> Tuple[int, int, bool]: - """Read a varint from the data starting at offset. Returns (value, bytes_read, is_complete). - is_complete is False if the varint was truncated (last byte doesn't have MSB set).""" - if offset >= len(data): - raise ValueError(f"Insufficient data for varint at offset {offset}") - - scratch = [] - count = 0 - is_complete = False - while offset + count < len(data): - byte = data[offset + count] - scratch.append(byte) - count += 1 - if byte & VAR_MASK == VAR_LAST: - is_complete = True - break - if count >= 10: - raise ValueError("Varint exceeded maximum length") - - # Check if we ran out of data before finding the last byte - if not is_complete and offset + count >= len(data): - # We've read all available bytes but the last one doesn't have MSB set - is_complete = False - - if offset + count > len(data): - raise ValueError(f"Insufficient data for varint: need {count} bytes, have {len(data) - offset}") - - value = 0 - for byte in reversed(scratch): - value = (value << VAR_OFFSET) | (byte & VAR_VAL_MASK) - - return (value, count, is_complete) - - -def read_prv(data: List[int], offset: int) -> Tuple[int, int, int]: - """Read privilege levels from a byte. Returns (from_prv, target_prv, bytes_read).""" - if offset >= len(data): - raise ValueError(f"Insufficient data for prv at offset {offset}") - - result = data[offset] - from_prv = result & 0b111 - target_prv = (result >> 3) & 0b111 - checksum = (result >> 6) & 0b11 - - if checksum != 0b10: - print(f"Warning: prv checksum should be 0b10, got {checksum:02b}") - - return (from_prv, target_prv, 1) - - -def decode_packet(data: List[int]) -> dict: - """Decode a single packet from byte data. Returns a dict with packet information.""" - if len(data) == 0: - raise ValueError("No data provided") - - first_byte = data[0] - result = { - "first_byte": f"0x{first_byte:02x} ({first_byte:08b})", - "is_compressed": False, - "bytes_read": 1, - "fields": {} - } - - c_header = first_byte & C_HEADER_MASK - - # Check if compressed - if c_header in [CHeader.CTb, CHeader.CNt, CHeader.CIj]: - result["is_compressed"] = True - result["c_header"] = CHeader.to_string(c_header) - - # Map CHeader to FHeader - if c_header == CHeader.CTb: - f_header_str = "FTb (taken branch)" - elif c_header == CHeader.CNt: - f_header_str = "FNt (not taken branch)" - else: # CIj - f_header_str = "FIj (inferable jump)" - - result["f_header"] = f_header_str - timestamp = (first_byte & C_TIMESTAMP_MASK) >> 2 - result["fields"]["timestamp"] = timestamp - result["description"] = f"Compressed packet: {result['c_header']}, timestamp={timestamp}" - - elif c_header == CHeader.CNa: - # Non-compressed packet - result["is_compressed"] = False - result["c_header"] = CHeader.to_string(c_header) - - f_header = (first_byte & F_HEADER_MASK) >> FHEADER_OFFSET - result["f_header"] = FHeader.to_string(f_header) - - offset = 1 - - if f_header in [FHeader.FTb, FHeader.FNt, FHeader.FIj]: - # Read timestamp varint - try: - timestamp, count, is_complete = read_varint(data, offset) - result["fields"]["timestamp"] = timestamp - result["bytes_read"] += count - offset += count - if not is_complete: - result["warnings"] = result.get("warnings", []) - result["warnings"].append(f"Timestamp varint is incomplete (last byte at offset {offset-1} doesn't have MSB set)") - result["description"] = f"Non-compressed packet: {result['f_header']}, timestamp={timestamp}" - except (ValueError, IndexError) as e: - result["error"] = f"Insufficient data for timestamp varint: {e}" - result["description"] = f"Non-compressed packet: {result['f_header']} (incomplete - need more bytes)" - - elif f_header == FHeader.FUj: - # Read target_address and timestamp varints - try: - target_address, count, is_complete = read_varint(data, offset) - result["fields"]["target_address"] = target_address - result["bytes_read"] += count - offset += count - if not is_complete: - result["warnings"] = result.get("warnings", []) - result["warnings"].append(f"Target address varint is incomplete (last byte at offset {offset-1} doesn't have MSB set)") - - timestamp, count, is_complete = read_varint(data, offset) - result["fields"]["timestamp"] = timestamp - result["bytes_read"] += count - offset += count - if not is_complete: - result["warnings"] = result.get("warnings", []) - result["warnings"].append(f"Timestamp varint is incomplete (last byte at offset {offset-1} doesn't have MSB set)") - result["description"] = f"Non-compressed packet: {result['f_header']}, target_address=0x{target_address:x}, timestamp={timestamp}" - except (ValueError, IndexError) as e: - result["error"] = f"Insufficient data for FUj packet: {e}" - result["description"] = f"Non-compressed packet: {result['f_header']} (incomplete - need more bytes)" - - elif f_header == FHeader.FSync: - # Read sync_type, prv, target_ctx, target_address, timestamp - sync_type = (first_byte & SYNC_TYPE_MASK) >> SYNC_TYPE_OFFSET - result["fields"]["sync_type"] = SyncType.to_string(sync_type) - - try: - from_prv, target_prv, count = read_prv(data, offset) - result["fields"]["from_prv"] = Prv.to_string(from_prv) - result["fields"]["target_prv"] = Prv.to_string(target_prv) - result["bytes_read"] += count - offset += count - - target_ctx, count, is_complete = read_varint(data, offset) - result["fields"]["target_ctx"] = target_ctx - result["bytes_read"] += count - offset += count - if not is_complete: - result["warnings"] = result.get("warnings", []) - result["warnings"].append(f"Target context varint is incomplete (last byte at offset {offset-1} doesn't have MSB set)") - - target_address, count, is_complete = read_varint(data, offset) - result["fields"]["target_address"] = target_address - result["bytes_read"] += count - offset += count - if not is_complete: - result["warnings"] = result.get("warnings", []) - result["warnings"].append(f"Target address varint is incomplete (last byte at offset {offset-1} doesn't have MSB set)") - - timestamp, count, is_complete = read_varint(data, offset) - result["fields"]["timestamp"] = timestamp - result["bytes_read"] += count - offset += count - if not is_complete: - result["warnings"] = result.get("warnings", []) - result["warnings"].append(f"Timestamp varint is incomplete (last byte at offset {offset-1} doesn't have MSB set)") - - result["description"] = ( - f"Non-compressed packet: {result['f_header']}, " - f"sync_type={result['fields']['sync_type']}, " - f"from_prv={result['fields']['from_prv']}, " - f"target_prv={result['fields']['target_prv']}, " - f"target_ctx={target_ctx}, " - f"target_address=0x{target_address:x}, " - f"timestamp={timestamp}" - ) - except (ValueError, IndexError) as e: - result["error"] = f"Insufficient data for FSync packet: {e}" - result["description"] = f"Non-compressed packet: {result['f_header']} (incomplete - need more bytes)" - - elif f_header == FHeader.FTrap: - # Read trap_type, prv, from_address, target_address, timestamp - trap_type = (first_byte & TRAP_TYPE_MASK) >> TRAP_TYPE_OFFSET - result["fields"]["trap_type"] = TrapType.to_string(trap_type) - - try: - from_prv, target_prv, count = read_prv(data, offset) - result["fields"]["from_prv"] = Prv.to_string(from_prv) - result["fields"]["target_prv"] = Prv.to_string(target_prv) - result["bytes_read"] += count - offset += count - - # TReturn with target_prv == PrvUser needs target_ctx - if trap_type == TrapType.TReturn and target_prv == Prv.PrvUser: - target_ctx, count, is_complete = read_varint(data, offset) - result["fields"]["target_ctx"] = target_ctx - result["bytes_read"] += count - offset += count - if not is_complete: - result["warnings"] = result.get("warnings", []) - result["warnings"].append(f"Target context varint is incomplete (last byte at offset {offset-1} doesn't have MSB set)") - - from_address, count, is_complete = read_varint(data, offset) - result["fields"]["from_address"] = from_address - result["bytes_read"] += count - offset += count - if not is_complete: - result["warnings"] = result.get("warnings", []) - result["warnings"].append(f"From address varint is incomplete (last byte at offset {offset-1} doesn't have MSB set)") - - target_address, count, is_complete = read_varint(data, offset) - result["fields"]["target_address"] = target_address - result["bytes_read"] += count - offset += count - if not is_complete: - result["warnings"] = result.get("warnings", []) - result["warnings"].append(f"Target address varint is incomplete (last byte at offset {offset-1} doesn't have MSB set)") - - timestamp, count, is_complete = read_varint(data, offset) - result["fields"]["timestamp"] = timestamp - result["bytes_read"] += count - offset += count - if not is_complete: - result["warnings"] = result.get("warnings", []) - result["warnings"].append(f"Timestamp varint is incomplete (last byte at offset {offset-1} doesn't have MSB set)") - - result["description"] = ( - f"Non-compressed packet: {result['f_header']}, " - f"trap_type={result['fields']['trap_type']}, " - f"from_prv={result['fields']['from_prv']}, " - f"target_prv={result['fields']['target_prv']}, " - f"from_address=0x{from_address:x}, " - f"target_address=0x{target_address:x}, " - f"timestamp={timestamp}" - ) - except (ValueError, IndexError) as e: - result["error"] = f"Insufficient data for FTrap packet: {e}" - result["description"] = f"Non-compressed packet: {result['f_header']} (incomplete - need more bytes)" - - else: - result["description"] = f"Non-compressed packet: {result['f_header']} (unhandled type)" - - else: - result["error"] = f"Invalid CHeader: {c_header:02b}" - result["description"] = f"Invalid packet: unknown CHeader {c_header:02b}" - - return result - - -def main(): - if len(sys.argv) < 2: - print("Usage: python3 decode_one.py [additional_bytes...]") - print("Example: python3 decode_one.py 80") - print("Example: python3 decode_one.py 80 12 34 56") - sys.exit(1) - - # Parse hex bytes from command line - data = [] - for arg in sys.argv[1:]: - try: - # Support both "80" and "0x80" formats - if arg.startswith("0x") or arg.startswith("0X"): - byte_val = int(arg, 16) - else: - byte_val = int(arg, 16) - - if byte_val < 0 or byte_val > 255: - print(f"Error: {arg} is not a valid byte (0-255)") - sys.exit(1) - - data.append(byte_val) - except ValueError: - print(f"Error: '{arg}' is not a valid hex byte") - sys.exit(1) - - if len(data) == 0: - print("Error: No valid bytes provided") - sys.exit(1) - - try: - packet = decode_packet(data) - - print("=" * 60) - print("PACKET DECODING") - print("=" * 60) - print(f"First byte: {packet['first_byte']}") - print(f"Compressed: {packet['is_compressed']}") - print(f"C Header: {packet.get('c_header', 'N/A')}") - print(f"F Header: {packet.get('f_header', 'N/A')}") - - if 'error' in packet: - print(f"\nERROR: {packet['error']}") - - if 'warnings' in packet: - print("\nWARNINGS:") - for warning in packet['warnings']: - print(f" ⚠ {warning}") - - if packet['fields']: - print("\nFields:") - for key, value in packet['fields'].items(): - print(f" {key}: {value}") - - print(f"\nBytes read: {packet['bytes_read']} (out of {len(data)} provided)") - - print("\n" + "=" * 60) - print("DESCRIPTION:") - print(packet['description']) - print("=" * 60) - - if packet['bytes_read'] < len(data): - print(f"\nNote: {len(data) - packet['bytes_read']} extra byte(s) provided but not used") - - except Exception as e: - print(f"Error decoding packet: {e}") - import traceback - traceback.print_exc() - sys.exit(1) - - -if __name__ == "__main__": - main() - diff --git a/scripts/filter_bp.py b/scripts/filter_bp.py deleted file mode 100644 index 3332bb4..0000000 --- a/scripts/filter_bp.py +++ /dev/null @@ -1,12 +0,0 @@ -# given a file, filter out the lines that start with [bp]: - -import sys - -def filter_bp(file_path): - with open(file_path, 'r') as file: - for line in file: - if line.startswith('[bp]'): - print(line) - -if __name__ == '__main__': - filter_bp(sys.argv[1]) \ No newline at end of file diff --git a/scripts/find_divergence_spike.py b/scripts/find_divergence_spike.py deleted file mode 100644 index b4b96dd..0000000 --- a/scripts/find_divergence_spike.py +++ /dev/null @@ -1,74 +0,0 @@ -# Parse the spike trace and the decoder dump to find any divergence - -import argparse - -def read_reference_file(reference_file): - """ - Reads the reference file and returns a list of addresses. - """ - with open(reference_file, 'r') as f: - reference_addresses = [line.strip().split(',')[0] for line in f.readlines()] - return reference_addresses - -def read_created_file(created_file): - """ - Reads the created file and returns a dictionary of addresses and their corresponding lines. - """ - created_data = {} - with open(created_file, 'r') as f: - for line in f: - if ':' in line and 'timestamp' not in line: - address, instruction = line.split(':', 1) - created_data[address.strip()] = instruction.strip() - return created_data - -def find_most_recent_divergence(reference_addresses, created_data): - """ - Finds the most recent divergence between the reference and created data. - """ - # first, get the first line of the created file - first_line_address = list(created_data.keys())[0] - # get the first occurrence of the first line address in the reference file - first_line_index = reference_addresses.index(first_line_address.split('0x')[1]) - - print(f"First line index: {first_line_index}") - - count = 0 - last_matching_address = None - # start from first_line_index and go through the reference file - - for address in reference_addresses[first_line_index:]: - # Convert address to the format used in the created file - formatted_address = '0x' + address.lower() - - if formatted_address in created_data: - last_matching_address = formatted_address - count += 1 - else: - print(f"Most recent divergence found at address: {formatted_address}") - return last_matching_address, formatted_address, count - - print("No divergence found. All addresses match.") - return last_matching_address, None, count - - -if __name__ == '__main__': - parser = argparse.ArgumentParser(description="Find divergence in trace.") - parser.add_argument("-r", "--ref_file", type=str, required=True, help="Path to the reference trace file.") - parser.add_argument("-d", "--decoder_dump", type=str, required=True, help="Path to the decoder dump file.") - args = parser.parse_args() - - reference_file = args.ref_file - decoder_dump = args.decoder_dump - - reference_addresses = read_reference_file(reference_file) - created_data = read_created_file(decoder_dump) - - last_match, divergence, count = find_most_recent_divergence(reference_addresses, created_data) - - if divergence: - print(f"Most recent match: {last_match}") - print(f"First divergence: {divergence}") - print(f"At line count: {count}") - else: - print(f"Everything matches up to the last reference address: {last_match}") diff --git a/scripts/find_divergence_verilator.py b/scripts/find_divergence_verilator.py deleted file mode 100644 index a5aa6e8..0000000 --- a/scripts/find_divergence_verilator.py +++ /dev/null @@ -1,124 +0,0 @@ -# Parse the verilator trace and the decoder dump to find any divergence - -import argparse -import re -def read_reference_file(reference_file): - """ - Reads the reference file and returns a list of addresses. - """ - with open(reference_file, 'r') as f: - reference_addresses = [line.strip() for line in f.readlines()] - # print(f"len(reference_addresses): {len(reference_addresses)}") - return reference_addresses - -def get_start_time(file): - with open(file, 'r') as f: - # get the first line - first_line = f.readline() - # [timestamp: 115213] Start - pattern = r"\[timestamp: (\d+)\]" - # print(f"first_line: {first_line}") - timestamp = int(re.search(pattern, first_line).group(1)) - return timestamp - -def find_start_of_trace(reference_addresses, start_time): - """ - Finds the line number containing the start time - """ - for i, line in enumerate(reference_addresses): - if str(start_time) in line: - return i - return None - -def parse_verilator_trace(reference_addresses, start_of_trace_index, length, target_address): - """ - Parses the verilator trace and returns a dictionary of addresses and their corresponding lines. - """ - # pattern: - # C0: 19 [1] pc=[0000000000010000] W[r10=0000000000010000][1] R[r 0=0000000000000000] R[r 0=0000000000000000] inst=[00000517] auipc a0, 0x0 - ref_data = [] - - extracted_pc = lambda line: line.split('pc=[')[1].split(']')[0] - # find the offset - offset = 0 - while True: - try: - ref_pc = extracted_pc(reference_addresses[start_of_trace_index - 1 + offset]) - # print(f"ref_pc: {ref_pc}") - # print(f"target_address: {target_address}") - except: - # print(f"start_of_trace_index: {start_of_trace_index - 1 + offset}") - # print(f"reference_addresses: {reference_addresses[start_of_trace_index - 1 + offset]}") - offset += 1 - continue - if target_address in ref_pc: - break - offset += 1 - - start = start_of_trace_index + offset - 1 - end = start + length + 1 - - for i in range(start, end): - try: - ref_data.append(extracted_pc(reference_addresses[i])) - except: - continue - return ref_data - - -def read_created_file(created_file): - """ - Reads the created file and returns a dictionary of addresses and their corresponding lines. - """ - created_data = [] - with open(created_file, 'r') as f: - for line in f: - if ':' in line and 'timestamp' not in line and "hit count" not in line: - address, instruction = line.split(':', 1) - created_data.append(address.strip().split('0x')[1]) - # print(len(created_data)) - return created_data - -def find_most_recent_divergence(reference_addresses, created_data, start_time): - """ - Finds the most recent divergence between the reference and created data. - """ - count = 0 - last_matching_address = None - - target_address = created_data[0] - - start_of_trace_index = find_start_of_trace(reference_addresses, start_time) - print(f"start_of_trace_index: {start_of_trace_index}") - ref_data = parse_verilator_trace(reference_addresses, start_of_trace_index, len(created_data), target_address) - - # matching the created data to the reference data - # print(len(ref_data)) - # print(len(created_data)) - for i, address in enumerate(created_data): - if address in ref_data[i]: - count += 1 - else: - print(f"Most recent divergence found at address: {address}") - print(f"reference data: {ref_data[i]}") - print(f"created data: {address}") - return False, count - return True, count - -if __name__ == '__main__': - parser = argparse.ArgumentParser(description="Find divergence in trace.") - parser.add_argument("-r", "--ref_file", type=str, required=True, help="Path to the reference trace file.") - parser.add_argument("-d", "--decoder_dump", type=str, required=True, help="Path to the decoder dump file.") - args = parser.parse_args() - - reference_file = args.ref_file - decoder_dump = args.decoder_dump - - reference_addresses = read_reference_file(reference_file) - created_data = read_created_file(decoder_dump) - start_time = get_start_time(decoder_dump) - match, count = find_most_recent_divergence(reference_addresses, created_data, start_time) - if match: - print(f"[SUCCESS] Everything matched up to the last line: {count}!") - else: - print(f"[FAILURE] Divergence found at line: {count}!") diff --git a/scripts/match_joints.py b/scripts/match_joints.py deleted file mode 100644 index 95666d8..0000000 --- a/scripts/match_joints.py +++ /dev/null @@ -1,68 +0,0 @@ -# A joint is where spike model decides to produce a packet -# This script matches the joints from the spike trace to the decoder dump - -import argparse -import re - -def read_reference_file(reference_file): - """ - Reads the reference file and returns a list of joint numbers in decimal. - """ - joint_pattern = r'\[joint\]\s*([0-9a-fA-F]+)' - with open(reference_file, 'r') as f: - reference_numbers = [] - for line in f: - match = re.search(joint_pattern, line) - if match: - reference_numbers.append(match.group(1)) - return reference_numbers - -def read_created_file(created_file): - """ - Reads the created file and returns a list of pc numbers in decimal. - """ - pc_pattern = r'pc:\s*([0-9a-fA-F]+)' - with open(created_file, 'r') as f: - created_data = [] - for line in f: - match = re.search(pc_pattern, line) - if match: - created_data.append(match.group(1)) - return created_data - -def find_most_recent_divergence(reference_numbers, created_data): - """ - Finds the most recent divergence between the reference and created data. - """ - count = 0 - last_matching_address = None - - for i,joint in enumerate(reference_numbers): - count += 1 - if i >= len(created_data): - print(f"Most recent divergence found at joint: {joint}") - return joint, None, count - if created_data[i] != joint: - print(f"Most recent divergence found at joint: {joint}") - return joint, created_data[i], count - print("No divergence found. All joints match.") - return None, None, count - -if __name__ == '__main__': - parser = argparse.ArgumentParser(description="Find divergence in trace.") - parser.add_argument("-r", "--ref_file", type=str, required=True, help="Path to the reference trace file.") - parser.add_argument("-d", "--decoder_dump", type=str, required=True, help="Path to the decoder dump file.") - args = parser.parse_args() - - reference_file = args.ref_file - decoder_dump = args.decoder_dump - - reference_numbers = read_reference_file(reference_file) - created_data = read_created_file(decoder_dump) - - last_match, divergence, count = find_most_recent_divergence(reference_numbers, created_data) - - if divergence: - print(f"Most recent reference joint: {last_match}") - print(f"First divergence: {divergence}") - print(f"At line count: {count}") \ No newline at end of file diff --git a/scripts/plot_distribution.py b/scripts/plot_distribution.py deleted file mode 100644 index 175a155..0000000 --- a/scripts/plot_distribution.py +++ /dev/null @@ -1,33 +0,0 @@ -# Given a sequence of iter: time pairs, plot the distribution of the times. - -import matplotlib.pyplot as plt -import numpy as np -import pandas as pd -import argparse -import re - -pattern = r'(\d+): (\d+)' - -def plot_distribution(input_file: str) -> None: - with open(input_file, 'r') as f: - content = f.read() - matches = re.findall(pattern, content) - times = [int(match[1]) for match in matches] - plt.hist(times, bins=100) - - print(f'{input_file}: {min(times)} to {max(times)}') - print(f'{input_file}: {sum(times) / len(times)} average') - print(f'{input_file}: {np.median(times)} median') - print(f'{input_file}: {np.percentile(times, 25)} 25th percentile') - print(f'{input_file}: {np.percentile(times, 75)} 75th percentile') - print(f'{input_file}: {np.percentile(times, 90)} 90th percentile') - print(f'{input_file}: {np.percentile(times, 95)} 95th percentile') - print(f'{input_file}: {np.percentile(times, 99)} 99th percentile') - - plt.savefig(f'{input_file}.png') - -if __name__ == '__main__': - parser = argparse.ArgumentParser() - parser.add_argument('--input', type=str, required=True) - args = parser.parse_args() - plot_distribution(args.input) \ No newline at end of file From bfeab47c9306a4633ad2347acc5df45167bce93d Mon Sep 17 00:00:00 2001 From: Lux Date: Sun, 22 Feb 2026 18:04:20 -0800 Subject: [PATCH 14/24] refactor: formatted everything --- src/backend/event.rs | 38 ++++++++-- src/common/insn_index.rs | 2 +- src/common/static_cfg.rs | 2 +- src/common/symbol_index.rs | 9 +-- src/frontend/decoder.rs | 97 +++++++++++++++++++------ src/frontend/decoder_cache.rs | 6 +- src/frontend/packet.rs | 11 +-- src/main.rs | 10 +-- src/receivers/abstract_receiver.rs | 2 +- src/receivers/bb_stats_receiver.rs | 64 ++++++++++++---- src/receivers/mod.rs | 8 +- src/receivers/path_profile_receiver.rs | 46 ++++++++---- src/receivers/prv_breakdown_receiver.rs | 48 ++++++++---- src/receivers/registry.rs | 8 +- src/receivers/speedscope_receiver.rs | 48 +++++++----- src/receivers/stack_txt_receiver.rs | 22 +++--- src/receivers/stack_unwinder.rs | 9 ++- src/receivers/tc_emulation_receiver.rs | 68 +++++++++-------- src/receivers/txt_receiver.rs | 8 +- 19 files changed, 344 insertions(+), 162 deletions(-) diff --git a/src/backend/event.rs b/src/backend/event.rs index 5b728b5..f7c9a4f 100644 --- a/src/backend/event.rs +++ b/src/backend/event.rs @@ -204,12 +204,38 @@ impl From for TrapReason { impl std::fmt::Display for EventKind { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - EventKind::TakenBranch { arc } => write!(f, "TakenBranch: {:#x} -> {:#x}", arc.0, arc.1), - EventKind::NonTakenBranch { arc } => write!(f, "NonTakenBranch: {:#x} -> {:#x}", arc.0, arc.1), - EventKind::UninferableJump { arc } => write!(f, "UninferableJump: {:#x} -> {:#x}", arc.0, arc.1), - EventKind::InferrableJump { arc } => write!(f, "InferrableJump: {:#x} -> {:#x}", arc.0, arc.1), - EventKind::Trap { reason, prv_arc, arc, ctx } => write!(f, "Trap: {:#x} -> {:#x} ({:?} {:?})", arc.0, arc.1, reason, prv_arc), - EventKind::SyncStart { runtime_cfg, start_pc, start_prv, start_ctx } => write!(f, "SyncStart: {:#x} ({:?} {:?}) {:?}", start_pc, start_prv, start_ctx, runtime_cfg), + EventKind::TakenBranch { arc } => { + write!(f, "TakenBranch: {:#x} -> {:#x}", arc.0, arc.1) + } + EventKind::NonTakenBranch { arc } => { + write!(f, "NonTakenBranch: {:#x} -> {:#x}", arc.0, arc.1) + } + EventKind::UninferableJump { arc } => { + write!(f, "UninferableJump: {:#x} -> {:#x}", arc.0, arc.1) + } + EventKind::InferrableJump { arc } => { + write!(f, "InferrableJump: {:#x} -> {:#x}", arc.0, arc.1) + } + EventKind::Trap { + reason, + prv_arc, + arc, + ctx, + } => write!( + f, + "Trap: {:#x} -> {:#x} ({:?} {:?})", + arc.0, arc.1, reason, prv_arc + ), + EventKind::SyncStart { + runtime_cfg, + start_pc, + start_prv, + start_ctx, + } => write!( + f, + "SyncStart: {:#x} ({:?} {:?}) {:?}", + start_pc, start_prv, start_ctx, runtime_cfg + ), EventKind::SyncEnd { end_pc } => write!(f, "SyncEnd: {:#x}", end_pc), EventKind::SyncPeriodic => write!(f, "SyncPeriodic"), EventKind::BPHit { hit_count } => write!(f, "BPHit: {}", hit_count), diff --git a/src/common/insn_index.rs b/src/common/insn_index.rs index afafbd5..baba370 100644 --- a/src/common/insn_index.rs +++ b/src/common/insn_index.rs @@ -4,12 +4,12 @@ use anyhow::Result; use log::{debug, trace}; use object::elf::SHF_EXECINSTR; use object::{Object, ObjectSection}; +use rustc_data_structures::fx::FxHashMap; use rvdasm::disassembler::*; use rvdasm::insn::Insn; use std::collections::HashMap; use std::fs::File; use std::io::{BufRead, BufReader, Read}; -use rustc_data_structures::fx::FxHashMap; pub struct InstructionIndex { asid_to_binary_id_map: HashMap, diff --git a/src/common/static_cfg.rs b/src/common/static_cfg.rs index f639fce..7348889 100644 --- a/src/common/static_cfg.rs +++ b/src/common/static_cfg.rs @@ -26,4 +26,4 @@ pub fn load_file_config(path: &str) -> Result { pub struct UserBinaryCfg { pub binary: String, pub asids: Vec, -} \ No newline at end of file +} diff --git a/src/common/symbol_index.rs b/src/common/symbol_index.rs index 122cd93..42c8f94 100644 --- a/src/common/symbol_index.rs +++ b/src/common/symbol_index.rs @@ -120,7 +120,8 @@ pub fn build_single_symbol_index( if exec_secs.contains(&sec_idx) { if let Ok(name) = symbol.name() { // filter out ghost symbols - if !name.starts_with("$x") && !name.starts_with("$d") && !name.starts_with(".L") { + if !name.starts_with("$x") && !name.starts_with("$d") && !name.starts_with(".L") + { let addr = symbol.address(); // lookup source location (may return None) let loc = loader.as_ref().map(|l| l.find_location(addr)); @@ -183,10 +184,8 @@ pub fn build_symbol_index(cfg: DecoderStaticCfg) -> Result { debug!("k_func_symbol_map size: {}", k_func_symbol_map.len()); for (binary, entry) in cfg.driver_binary_entry_tuples { let driver_entry_point = u64::from_str_radix(entry.trim_start_matches("0x"), 16)?; - let func_symbol_map = build_single_symbol_index( - binary.clone(), - Prv::PrvSupervisor, - driver_entry_point)?; + let func_symbol_map = + build_single_symbol_index(binary.clone(), Prv::PrvSupervisor, driver_entry_point)?; k_func_symbol_map.extend(func_symbol_map); debug!("k_func_symbol_map size: {}", k_func_symbol_map.len()); } diff --git a/src/frontend/decoder.rs b/src/frontend/decoder.rs index 66fbddc..fb57849 100644 --- a/src/frontend/decoder.rs +++ b/src/frontend/decoder.rs @@ -1,7 +1,7 @@ use anyhow::Result; use bus::Bus; use indicatif::{ProgressBar, ProgressStyle}; -use log::{warn, debug, trace}; +use log::{debug, trace, warn}; use std::fs::File; use std::io::BufReader; @@ -11,16 +11,16 @@ use crate::common::prv::Prv; use crate::common::static_cfg::DecoderStaticCfg; use crate::frontend::bp_double_saturating_counter::BpDoubleSaturatingCounter; use crate::frontend::br_mode::BrMode; +use crate::frontend::decoder_cache::{BasicBlockStats, DecoderCache}; use crate::frontend::f_header::FHeader; -use crate::frontend::packet::{Packet, PacketReader, read_first_packet}; +use crate::frontend::packet::{read_first_packet, Packet, PacketReader}; use crate::frontend::runtime_cfg::DecoderRuntimeCfg; use crate::frontend::trap_type::TrapType; -use crate::frontend::decoder_cache::{BasicBlockStats, DecoderCache}; use rustc_data_structures::fx::FxHashMap; use rvdasm::insn::Insn; -use std::sync::Arc; use std::collections::HashSet; +use std::sync::Arc; // const ADDR_BITS: u64 = 64; const ADDR_BITS: u64 = 40; @@ -96,7 +96,14 @@ fn refund_addr(addr: u64) -> u64 { } // step until encountering a br/jump -fn step_bb(pc: u64, insn_map: &FxHashMap, bus: &mut Bus, br_mode: &BrMode, decoder_cache: &mut DecoderCache, insn_count: &mut u64) -> u64 { +fn step_bb( + pc: u64, + insn_map: &FxHashMap, + bus: &mut Bus, + br_mode: &BrMode, + decoder_cache: &mut DecoderCache, + insn_count: &mut u64, +) -> u64 { let initial_pc = pc; let mut pc = pc; if let Some(basic_block_stats) = decoder_cache.get(pc) { @@ -120,15 +127,20 @@ fn step_bb(pc: u64, insn_map: &FxHashMap, bus: &mut Bus, br_mo if insn.is_branch() || insn.is_indirect_jump() { break; } else if insn.is_direct_jump() { - let new_pc = - (pc as i64 + insn.offset as i64) as u64; + let new_pc = (pc as i64 + insn.offset as i64) as u64; pc = new_pc; } else { pc += insn.len as u64; } } } - decoder_cache.insert(initial_pc, BasicBlockStats { target_pc: pc, num_instructions }); + decoder_cache.insert( + initial_pc, + BasicBlockStats { + target_pc: pc, + num_instructions, + }, + ); *insn_count += num_instructions; pc } @@ -218,8 +230,7 @@ pub fn decode_trace( loop { match packet_reader.read_packet(&mut packet) { - Ok(n) => - { + Ok(n) => { bytes_read += n; if !u_unknown_ctx || prv != Prv::PrvUser { known_ctx_bytes_read += n; @@ -236,7 +247,7 @@ pub fn decode_trace( progress_bar.set_position(bytes_read); last_progress_update = bytes_read; } - + debug!("packet: {:?}", packet); // packet_count += 1; @@ -263,8 +274,13 @@ pub fn decode_trace( // only step if we are in a known ctx let trapping_pc = refund_addr(packet.from_address); if !(u_unknown_ctx && prv == Prv::PrvUser) { - let new_pc = - step_bb_until(pc.get_addr(), curr_insn_map, trapping_pc, &mut bus, &mut insn_count); + let new_pc = step_bb_until( + pc.get_addr(), + curr_insn_map, + trapping_pc, + &mut bus, + &mut insn_count, + ); assert!( new_pc == trapping_pc, "new_pc: {:x}, trapping_pc: {:x}", @@ -296,7 +312,7 @@ pub fn decode_trace( } ctx = packet.target_ctx; u_unknown_ctx = false; // we now are in a known ctx - // decode_cache.flush(); // flush the decode cachedd after reporting the trap event with ctx + // decode_cache.flush(); // flush the decode cachedd after reporting the trap event with ctx } else { u_unknown_ctx = true; // we are in an unknown ctx } @@ -329,7 +345,14 @@ pub fn decode_trace( packet.timestamp, )); for _ in 0..packet.timestamp { - let new_pc = step_bb(pc.get_addr(), curr_insn_map, &mut bus, &br_mode, &mut decoder_cache, &mut insn_count); + let new_pc = step_bb( + pc.get_addr(), + curr_insn_map, + &mut bus, + &br_mode, + &mut decoder_cache, + &mut insn_count, + ); pc.set_addr(new_pc); let insn_to_resolve = curr_insn_map.get(&pc.get_addr()).unwrap(); if !insn_to_resolve.is_branch() { @@ -360,7 +383,14 @@ pub fn decode_trace( // predicted miss timestamp += packet.timestamp; bus.broadcast(Entry::event(EventKind::bpmiss(), timestamp)); - let new_pc = step_bb(pc.get_addr(), curr_insn_map, &mut bus, &br_mode, &mut decoder_cache, &mut insn_count); + let new_pc = step_bb( + pc.get_addr(), + curr_insn_map, + &mut bus, + &br_mode, + &mut decoder_cache, + &mut insn_count, + ); pc.set_addr(new_pc); let insn_to_resolve = curr_insn_map.get(&pc.get_addr()).unwrap(); if !insn_to_resolve.is_branch() { @@ -375,8 +405,8 @@ pub fn decode_trace( let taken = bp_counter.predict(pc.get_addr(), false); if !taken { // let new_pc = (pc.get_addr() as i64 - // + insn_to_resolve.get_imm().unwrap().get_val_signed_imm() as i64) - // as u64; + // + insn_to_resolve.get_imm().unwrap().get_val_signed_imm() as i64) + // as u64; let new_pc = (pc.get_addr() as i64 + insn_to_resolve.offset as i64) as u64; bus.broadcast(Entry::event( EventKind::taken_branch((pc.get_addr(), new_pc)), @@ -399,7 +429,14 @@ pub fn decode_trace( continue; } // only enter here if we are either in a known ctx or we are in a unknown ctx and we are in a supervisor priv - let new_pc = step_bb(pc.get_addr(), curr_insn_map, &mut bus, &br_mode, &mut decoder_cache, &mut insn_count); + let new_pc = step_bb( + pc.get_addr(), + curr_insn_map, + &mut bus, + &br_mode, + &mut decoder_cache, + &mut insn_count, + ); pc.set_addr(new_pc); trace!("setting pc to: {:x}", pc.get_addr()); let insn_to_resolve = curr_insn_map.get(&pc.get_addr()).unwrap(); @@ -465,7 +502,11 @@ pub fn decode_trace( EventKind::inferrable_jump((old_pc_to_report, new_pc_to_report)), timestamp, )); - trace!("inferrable jump: {:x} -> {:x}", old_pc_to_report, new_pc_to_report); + trace!( + "inferrable jump: {:x} -> {:x}", + old_pc_to_report, + new_pc_to_report + ); } FHeader::FUj => { if !insn_to_resolve.is_indirect_jump() { @@ -485,7 +526,11 @@ pub fn decode_trace( EventKind::uninferable_jump((old_pc_to_report, new_pc_to_report)), timestamp, )); - trace!("uninferable jump: {:x} -> {:x}", old_pc_to_report, new_pc_to_report); + trace!( + "uninferable jump: {:x} -> {:x}", + old_pc_to_report, + new_pc_to_report + ); } _ => { bus.broadcast(Entry::event(EventKind::panic(), 0)); @@ -501,8 +546,14 @@ pub fn decode_trace( println!("insn_count: {}", insn_count); println!("file size: {} bytes", trace_file_size); println!("known ctx bytes read: {} bytes", known_ctx_bytes_read); - println!("bits per instruction: {:.4}", known_ctx_bytes_read as f64 * 8.0 / insn_count as f64); - println!("compressed packet count: {}", packet_reader.compressed_packet_count); + println!( + "bits per instruction: {:.4}", + known_ctx_bytes_read as f64 * 8.0 / insn_count as f64 + ); + println!( + "compressed packet count: {}", + packet_reader.compressed_packet_count + ); println!("full packet count: {}", packet_reader.full_packet_count); Ok(()) } diff --git a/src/frontend/decoder_cache.rs b/src/frontend/decoder_cache.rs index eebd770..49c9a93 100644 --- a/src/frontend/decoder_cache.rs +++ b/src/frontend/decoder_cache.rs @@ -12,7 +12,9 @@ pub struct DecoderCache { impl DecoderCache { pub fn new() -> Self { - Self { cache: FxHashMap::default() } + Self { + cache: FxHashMap::default(), + } } pub fn get(&self, pc: u64) -> Option<&BasicBlockStats> { @@ -30,4 +32,4 @@ impl DecoderCache { pub fn reset(&mut self) { self.cache.clear(); } -} \ No newline at end of file +} diff --git a/src/frontend/packet.rs b/src/frontend/packet.rs index 9946606..ab2618c 100644 --- a/src/frontend/packet.rs +++ b/src/frontend/packet.rs @@ -71,7 +71,11 @@ pub struct PacketReader { impl PacketReader { pub fn new(stream: BufReader) -> Self { - Self { stream, compressed_packet_count: 0, full_packet_count: 0 } + Self { + stream, + compressed_packet_count: 0, + full_packet_count: 0, + } } pub fn read_packet(&mut self, packet: &mut Packet) -> Result<(u64)> { @@ -168,10 +172,8 @@ impl PacketReader { } Ok(bytes_read) } - } - fn read_varint(stream: &mut BufReader) -> Result<(u64, u64)> { let mut scratch = [0u8; 10]; let mut count = 0usize; @@ -206,13 +208,12 @@ fn read_prv(stream: &mut BufReader) -> Result<(Prv, Prv)> { // returns the number of bytes read - pub fn read_first_packet(stream: &mut BufReader) -> Result<(Packet, DecoderRuntimeCfg)> { let mut packet = Packet::new(); let first_byte = read_u8(stream)?; trace!("first_byte: {:08b}", first_byte); let mut bytes_read = 1; - + let c_header = CHeader::from(first_byte & C_HEADER_MASK); if c_header != CHeader::CNa { return Err(anyhow::anyhow!( diff --git a/src/main.rs b/src/main.rs index e804ee1..86be0e9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,8 +5,8 @@ extern crate gcno_reader; extern crate indicatif; extern crate log; extern crate object; -extern crate rvdasm; extern crate rustc_data_structures; +extern crate rvdasm; mod frontend { pub mod bp_double_saturating_counter; @@ -43,8 +43,8 @@ use std::io::{BufReader, Read}; use clap::Parser; use object::Object; // path dependency -use std::path::Path; use std::io::Write; +use std::path::Path; // bus dependency use bus::Bus; use std::thread; @@ -175,7 +175,8 @@ fn main() -> Result<()> { let receiver_cfg = static_cfg.receivers.clone(); if !receiver_cfg.is_empty() { - let shared = receivers::abstract_receiver::Shared::new(&static_cfg.clone(), &runtime_cfg.clone())?; + let shared = + receivers::abstract_receiver::Shared::new(&static_cfg.clone(), &runtime_cfg.clone())?; for (name, cfg) in receiver_cfg.iter() { let enabled = cfg @@ -186,8 +187,7 @@ fn main() -> Result<()> { continue; } let bus_rx = bus.add_rx(); - let receiver = - registry::make_receiver(name, &shared, cfg.clone(), bus_rx)?; + let receiver = registry::make_receiver(name, &shared, cfg.clone(), bus_rx)?; receivers.push(receiver); } } diff --git a/src/receivers/abstract_receiver.rs b/src/receivers/abstract_receiver.rs index 6e07591..bf18421 100644 --- a/src/receivers/abstract_receiver.rs +++ b/src/receivers/abstract_receiver.rs @@ -59,4 +59,4 @@ impl Shared { insn_index: Arc::new(build_instruction_index(static_cfg.clone())?), }) } -} \ No newline at end of file +} diff --git a/src/receivers/bb_stats_receiver.rs b/src/receivers/bb_stats_receiver.rs index 22a480a..3d9fe53 100644 --- a/src/receivers/bb_stats_receiver.rs +++ b/src/receivers/bb_stats_receiver.rs @@ -1,6 +1,6 @@ -use crate::receivers::abstract_receiver::{AbstractReceiver, BusReceiver, Shared}; use crate::backend::event::{Entry, EventKind}; use crate::common::prv::Prv; +use crate::receivers::abstract_receiver::{AbstractReceiver, BusReceiver, Shared}; use bus::BusReader; use std::collections::HashMap; @@ -22,11 +22,16 @@ pub struct BBStatsReceiver { prev_timestamp: u64, asid_of_interest: Vec, prv_of_interest: Vec, - interested: bool + interested: bool, } impl BBStatsReceiver { - pub fn new(bus_rx: BusReader, path: String, asid_of_interest: Vec, prv_of_interest: Vec) -> Self { + pub fn new( + bus_rx: BusReader, + path: String, + asid_of_interest: Vec, + prv_of_interest: Vec, + ) -> Self { Self { writer: BufWriter::new(File::create(path).unwrap()), receiver: BusReceiver { @@ -49,19 +54,46 @@ pub fn factory( _config: serde_json::Value, bus_rx: BusReader, ) -> Box { - let path = _config.get("path").and_then(|value| value.as_str()).unwrap_or("trace.bb_stats.csv").to_string(); - let asid_of_interest = _config.get("asid_of_interest").and_then(|value| value.as_array()).unwrap_or(&vec![]).iter().map(|value| value.as_u64().unwrap()).collect(); + let path = _config + .get("path") + .and_then(|value| value.as_str()) + .unwrap_or("trace.bb_stats.csv") + .to_string(); + let asid_of_interest = _config + .get("asid_of_interest") + .and_then(|value| value.as_array()) + .unwrap_or(&vec![]) + .iter() + .map(|value| value.as_u64().unwrap()) + .collect(); let mut prv_of_interest = vec![]; - if _config.get("do_user").and_then(|value| value.as_bool()).unwrap_or(false) { + if _config + .get("do_user") + .and_then(|value| value.as_bool()) + .unwrap_or(false) + { prv_of_interest.push(Prv::PrvUser); } - if _config.get("do_supervisor").and_then(|value| value.as_bool()).unwrap_or(false) { + if _config + .get("do_supervisor") + .and_then(|value| value.as_bool()) + .unwrap_or(false) + { prv_of_interest.push(Prv::PrvSupervisor); } - if _config.get("do_machine").and_then(|value| value.as_bool()).unwrap_or(false) { + if _config + .get("do_machine") + .and_then(|value| value.as_bool()) + .unwrap_or(false) + { prv_of_interest.push(Prv::PrvMachine); } - Box::new(BBStatsReceiver::new(bus_rx, path, asid_of_interest, prv_of_interest)) + Box::new(BBStatsReceiver::new( + bus_rx, + path, + asid_of_interest, + prv_of_interest, + )) } crate::register_receiver!("bb_stats", factory); @@ -136,7 +168,13 @@ impl AbstractReceiver for BBStatsReceiver { } Entry::Event { timestamp, - kind: EventKind::Trap { reason: _, prv_arc, arc, ctx }, + kind: + EventKind::Trap { + reason: _, + prv_arc, + arc, + ctx, + }, } => { if self.prv_of_interest.contains(&prv_arc.1) { if prv_arc.1 == Prv::PrvUser { @@ -174,11 +212,7 @@ impl AbstractReceiver for BBStatsReceiver { .write_all( format!( "{}, {}, {}, {:#x}-{:#x}\n", - count, - mean, - netvar, - bb.start_addr, - bb.end_addr, + count, mean, netvar, bb.start_addr, bb.end_addr, ) .as_bytes(), ) diff --git a/src/receivers/mod.rs b/src/receivers/mod.rs index 92f2a66..00ce5f7 100644 --- a/src/receivers/mod.rs +++ b/src/receivers/mod.rs @@ -2,16 +2,16 @@ pub mod abstract_receiver; pub mod registry; pub mod stack_unwinder; -pub mod txt_receiver; +pub mod bb_stats_receiver; +pub mod path_profile_receiver; pub mod prv_breakdown_receiver; pub mod speedscope_receiver; pub mod stack_txt_receiver; -pub mod bb_stats_receiver; -pub mod path_profile_receiver; pub mod tc_emulation_receiver; +pub mod txt_receiver; // TODO: mask off for now until verified again // pub mod afdo_receiver; // pub mod gcda_receiver; // pub mod atomic_receiver; -// pub mod perfetto_receiver; \ No newline at end of file +// pub mod perfetto_receiver; diff --git a/src/receivers/path_profile_receiver.rs b/src/receivers/path_profile_receiver.rs index 81b3e02..188581e 100644 --- a/src/receivers/path_profile_receiver.rs +++ b/src/receivers/path_profile_receiver.rs @@ -1,7 +1,7 @@ -use crate::receivers::abstract_receiver::{AbstractReceiver, BusReceiver, Shared}; use crate::backend::event::{Entry, EventKind}; -use crate::receivers::stack_unwinder::StackUnwinder; use crate::common::symbol_index::SymbolIndex; +use crate::receivers::abstract_receiver::{AbstractReceiver, BusReceiver, Shared}; +use crate::receivers::stack_unwinder::StackUnwinder; use bus::BusReader; use std::collections::HashMap; use std::fs::File; @@ -23,7 +23,11 @@ pub struct PathStats { impl PathStats { pub fn new(duration: u64) -> Self { - Self { count: 1, min: duration, sum: duration } + Self { + count: 1, + min: duration, + sum: duration, + } } pub fn update(&mut self, duration: u64) { @@ -56,13 +60,8 @@ pub struct PathProfileReceiver { } impl PathProfileReceiver { - pub fn new( - bus_rx: BusReader, - symbols: Arc, - path: String, - ) -> Self { - let unwinder = - StackUnwinder::new(Arc::clone(&symbols)).expect("stack unwinder"); + pub fn new(bus_rx: BusReader, symbols: Arc, path: String) -> Self { + let unwinder = StackUnwinder::new(Arc::clone(&symbols)).expect("stack unwinder"); Self { writer: BufWriter::new(File::create(path).unwrap()), receiver: BusReceiver { @@ -83,8 +82,16 @@ pub fn factory( _config: serde_json::Value, bus_rx: BusReader, ) -> Box { - let path = _config.get("path").and_then(|value| value.as_str()).unwrap_or("trace.path_profile.csv").to_string(); - Box::new(PathProfileReceiver::new(bus_rx, _shared.symbol_index.clone(), path)) + let path = _config + .get("path") + .and_then(|value| value.as_str()) + .unwrap_or("trace.path_profile.csv") + .to_string(); + Box::new(PathProfileReceiver::new( + bus_rx, + _shared.symbol_index.clone(), + path, + )) } crate::register_receiver!("path_profile", factory); @@ -167,12 +174,23 @@ impl AbstractReceiver for PathProfileReceiver { fn _flush(&mut self) { // path net variation time(i)= total path execution time(i)–(path frequency(i) x (path basetime(i))) - self.writer.write_all(format!("count,mean,netvar,path\n").as_bytes()).unwrap(); + self.writer + .write_all(format!("count,mean,netvar,path\n").as_bytes()) + .unwrap(); for (path, records) in self.path_records.iter() { // compute mean and standard deviation let net_var = records.sum as f64 - (records.count as f64 * records.min as f64); self.writer - .write_all(format!("{}, {}, {}, {}\n", records.count, records.sum as f64 / records.count as f64, net_var, path.to_string()).as_bytes()) + .write_all( + format!( + "{}, {}, {}, {}\n", + records.count, + records.sum as f64 / records.count as f64, + net_var, + path.to_string() + ) + .as_bytes(), + ) .unwrap(); } self.writer.flush().unwrap(); diff --git a/src/receivers/prv_breakdown_receiver.rs b/src/receivers/prv_breakdown_receiver.rs index d00e0d5..1a3ac1b 100644 --- a/src/receivers/prv_breakdown_receiver.rs +++ b/src/receivers/prv_breakdown_receiver.rs @@ -1,7 +1,7 @@ -use crate::receivers::abstract_receiver::{AbstractReceiver, BusReceiver, Shared}; use crate::backend::event::{Entry, EventKind}; -use bus::BusReader; use crate::common::prv::Prv; +use crate::receivers::abstract_receiver::{AbstractReceiver, BusReceiver, Shared}; +use bus::BusReader; /* Receiver for answering the question: "How many cycles were executed in each privilege level?" */ pub struct PrvBreakdownReceiver { @@ -51,31 +51,49 @@ impl AbstractReceiver for PrvBreakdownReceiver { fn _receive_entry(&mut self, entry: Entry) { match entry { - Entry::Event { timestamp, kind: EventKind::SyncStart { start_prv, .. } } => { + Entry::Event { + timestamp, + kind: EventKind::SyncStart { start_prv, .. }, + } => { self.curr_prv = start_prv; self.prev_timestamp = timestamp; } - Entry::Event { timestamp, kind: EventKind::Trap { prv_arc, .. } } => { - self.update_prv_cycles(timestamp); - self.curr_prv = prv_arc.1; + Entry::Event { + timestamp, + kind: EventKind::Trap { prv_arc, .. }, + } => { + self.update_prv_cycles(timestamp); + self.curr_prv = prv_arc.1; } Entry::Event { timestamp, .. } => { - self.update_prv_cycles(timestamp); + self.update_prv_cycles(timestamp); } Entry::Instruction { .. } => { - // do nothing + // do nothing } } } fn _flush(&mut self) { - println!("--------------------------------"); - println!("Privilege level breakdown:"); - let total_cycles = self.u_prv_cycles + self.k_prv_cycles + self.m_prv_cycles; - println!("User privilege level cycles: {} ({:.2}%)", self.u_prv_cycles, self.u_prv_cycles as f64 / total_cycles as f64 * 100.0); - println!("Supervisor privilege level cycles: {} ({:.2}%)", self.k_prv_cycles, self.k_prv_cycles as f64 / total_cycles as f64 * 100.0); - println!("Machine privilege level cycles: {} ({:.2}%)", self.m_prv_cycles, self.m_prv_cycles as f64 / total_cycles as f64 * 100.0); - println!("--------------------------------"); + println!("--------------------------------"); + println!("Privilege level breakdown:"); + let total_cycles = self.u_prv_cycles + self.k_prv_cycles + self.m_prv_cycles; + println!( + "User privilege level cycles: {} ({:.2}%)", + self.u_prv_cycles, + self.u_prv_cycles as f64 / total_cycles as f64 * 100.0 + ); + println!( + "Supervisor privilege level cycles: {} ({:.2}%)", + self.k_prv_cycles, + self.k_prv_cycles as f64 / total_cycles as f64 * 100.0 + ); + println!( + "Machine privilege level cycles: {} ({:.2}%)", + self.m_prv_cycles, + self.m_prv_cycles as f64 / total_cycles as f64 * 100.0 + ); + println!("--------------------------------"); } } diff --git a/src/receivers/registry.rs b/src/receivers/registry.rs index 140658b..66ee46b 100644 --- a/src/receivers/registry.rs +++ b/src/receivers/registry.rs @@ -3,9 +3,11 @@ use crate::receivers::abstract_receiver::{AbstractReceiver, Shared}; use anyhow::Result; use bus::BusReader; -pub type ReceiverFactory = - fn(shared: &Shared, config: serde_json::Value, bus_rx: BusReader) - -> Box; +pub type ReceiverFactory = fn( + shared: &Shared, + config: serde_json::Value, + bus_rx: BusReader, +) -> Box; pub struct ReceiverRegistration { pub name: &'static str, diff --git a/src/receivers/speedscope_receiver.rs b/src/receivers/speedscope_receiver.rs index 0fd59bd..3aeec5d 100644 --- a/src/receivers/speedscope_receiver.rs +++ b/src/receivers/speedscope_receiver.rs @@ -1,8 +1,8 @@ -use crate::receivers::abstract_receiver::{AbstractReceiver, BusReceiver, Shared}; use crate::backend::event::{Entry, EventKind}; -use crate::receivers::stack_unwinder::{Frame, StackUnwinder, StackUpdateResult}; use crate::common::prv::Prv; use crate::common::symbol_index::SymbolIndex; +use crate::receivers::abstract_receiver::{AbstractReceiver, BusReceiver, Shared}; +use crate::receivers::stack_unwinder::{Frame, StackUnwinder, StackUpdateResult}; use bus::BusReader; use log::{debug, warn}; use serde::Serialize; @@ -58,15 +58,10 @@ pub struct SpeedscopeReceiver { } impl SpeedscopeReceiver { - pub fn new( - bus_rx: BusReader, - symbols: Arc, - path: String, - ) -> Self { + pub fn new(bus_rx: BusReader, symbols: Arc, path: String) -> Self { debug!("SpeedscopeReceiver::new"); - let unwinder = - StackUnwinder::new(Arc::clone(&symbols)).expect("stack unwinder"); + let unwinder = StackUnwinder::new(Arc::clone(&symbols)).expect("stack unwinder"); let (frames, frame_lookup) = build_frames(&symbols); @@ -93,8 +88,16 @@ pub fn factory( _config: serde_json::Value, bus_rx: BusReader, ) -> Box { - let path = _config.get("path").and_then(|value| value.as_str()).unwrap_or("trace.speedscope.json").to_string(); - Box::new(SpeedscopeReceiver::new(bus_rx, _shared.symbol_index.clone(), path)) + let path = _config + .get("path") + .and_then(|value| value.as_str()) + .unwrap_or("trace.speedscope.json") + .to_string(); + Box::new(SpeedscopeReceiver::new( + bus_rx, + _shared.symbol_index.clone(), + path, + )) } crate::register_receiver!("speedscope", factory); @@ -127,9 +130,7 @@ impl SpeedscopeReceiver { } fn lookup_frame(&self, frame: &Frame) -> Option { - let id = self - .frame_lookup - .lookup(frame.prv, frame.ctx, frame.addr); + let id = self.frame_lookup.lookup(frame.prv, frame.ctx, frame.addr); id } @@ -139,15 +140,22 @@ impl SpeedscopeReceiver { } if self.curr_ctx != 0 { if let Some(id) = self.frame_lookup.asid_lookup.get(&self.curr_ctx) { - self.events.push(ProfileEvent { kind: "C".into(), frame: *id, at: ts }); + self.events.push(ProfileEvent { + kind: "C".into(), + frame: *id, + at: ts, + }); } } if let Some(id) = self.frame_lookup.asid_lookup.get(&ctx) { - self.events.push(ProfileEvent { kind: "O".into(), frame: *id, at: ts }); + self.events.push(ProfileEvent { + kind: "O".into(), + frame: *id, + at: ts, + }); } self.curr_ctx = ctx; } - } impl AbstractReceiver for SpeedscopeReceiver { @@ -221,7 +229,11 @@ impl AbstractReceiver for SpeedscopeReceiver { } if let Some(id) = self.frame_lookup.asid_lookup.get(&self.curr_ctx) { - self.events.push(ProfileEvent { kind: "C".into(), frame: *id, at: self.end }); + self.events.push(ProfileEvent { + kind: "C".into(), + frame: *id, + at: self.end, + }); } write_speedscope( diff --git a/src/receivers/stack_txt_receiver.rs b/src/receivers/stack_txt_receiver.rs index 456b997..8a75915 100644 --- a/src/receivers/stack_txt_receiver.rs +++ b/src/receivers/stack_txt_receiver.rs @@ -1,7 +1,7 @@ -use crate::receivers::abstract_receiver::{AbstractReceiver, BusReceiver, Shared}; use crate::backend::event::Entry; -use crate::receivers::stack_unwinder::{StackUnwinder, StackUpdateResult}; use crate::common::symbol_index::SymbolIndex; +use crate::receivers::abstract_receiver::{AbstractReceiver, BusReceiver, Shared}; +use crate::receivers::stack_unwinder::{StackUnwinder, StackUpdateResult}; use bus::BusReader; use std::fs::File; use std::io::{BufWriter, Write}; @@ -14,11 +14,7 @@ pub struct StackTxtReceiver { } impl StackTxtReceiver { - pub fn new( - bus_rx: BusReader, - symbols: Arc, - path: String, - ) -> Self { + pub fn new(bus_rx: BusReader, symbols: Arc, path: String) -> Self { let unwinder = StackUnwinder::new(symbols).expect("init unwinder"); Self { writer: BufWriter::new(File::create(path).unwrap()), @@ -37,8 +33,16 @@ pub fn factory( _config: serde_json::Value, bus_rx: BusReader, ) -> Box { - let path = _config.get("path").and_then(|value| value.as_str()).unwrap_or("trace.stack.txt").to_string(); - Box::new(StackTxtReceiver::new(bus_rx, Arc::clone(&_shared.symbol_index), path)) + let path = _config + .get("path") + .and_then(|value| value.as_str()) + .unwrap_or("trace.stack.txt") + .to_string(); + Box::new(StackTxtReceiver::new( + bus_rx, + Arc::clone(&_shared.symbol_index), + path, + )) } crate::register_receiver!("stack_txt", factory); diff --git a/src/receivers/stack_unwinder.rs b/src/receivers/stack_unwinder.rs index 331f8a5..262e24a 100644 --- a/src/receivers/stack_unwinder.rs +++ b/src/receivers/stack_unwinder.rs @@ -31,9 +31,7 @@ pub struct StackUpdateResult { } impl StackUnwinder { - pub fn new( - func_symbol_map: Arc, - ) -> Result { + pub fn new(func_symbol_map: Arc) -> Result { Ok(Self { func_symbol_map: func_symbol_map, frame_stack: Vec::new(), @@ -176,7 +174,10 @@ impl StackUnwinder { frames_closed: Vec::new(), }); } else { - panic!("failed to push frame for exception or interrupt, got target 0x{:08x}", to_addr); + panic!( + "failed to push frame for exception or interrupt, got target 0x{:08x}", + to_addr + ); } } TrapReason::Return => { diff --git a/src/receivers/tc_emulation_receiver.rs b/src/receivers/tc_emulation_receiver.rs index 85368b8..ae0dd00 100644 --- a/src/receivers/tc_emulation_receiver.rs +++ b/src/receivers/tc_emulation_receiver.rs @@ -1,5 +1,5 @@ -use crate::receivers::abstract_receiver::{AbstractReceiver, BusReceiver, Shared}; use crate::backend::event::{Entry, EventKind}; +use crate::receivers::abstract_receiver::{AbstractReceiver, BusReceiver, Shared}; use bus::BusReader; use std::fs::File; use std::io::{BufWriter, Write}; @@ -12,7 +12,7 @@ pub struct TcEmulationReceiver { event_staging: Vec, } -/* Emulates the behavior of a TC-based encoder, used for accuracy analysis +/* Emulates the behavior of a TC-based encoder, used for accuracy analysis A TC-based encoder encodes timestamp as separate packets emitted in fixed intervals. */ impl TcEmulationReceiver { @@ -36,8 +36,15 @@ pub fn factory( _config: serde_json::Value, bus_rx: BusReader, ) -> Box { - let path = _config.get("path").and_then(|value| value.as_str()).unwrap_or("trace.tc_emulation.txt").to_string(); - let interval = _config.get("interval").and_then(|value| value.as_u64()).unwrap_or(1000000); + let path = _config + .get("path") + .and_then(|value| value.as_str()) + .unwrap_or("trace.tc_emulation.txt") + .to_string(); + let interval = _config + .get("interval") + .and_then(|value| value.as_u64()) + .unwrap_or(1000000); Box::new(TcEmulationReceiver::new(bus_rx, path, interval)) } @@ -54,32 +61,35 @@ impl AbstractReceiver for TcEmulationReceiver { fn _receive_entry(&mut self, entry: Entry) { match entry { - Entry::Event { timestamp, kind: EventKind::SyncStart { .. } } => { - self.curr_tc = timestamp / self.interval; - } - Entry::Event { timestamp, kind } => { - if timestamp / self.interval != self.curr_tc { - // smear the timestamps distributing across all events staged, excluding the current event - let slack = (timestamp / self.interval - self.curr_tc) * self.interval; - let num_events = self.event_staging.len() as u64; - let delta_tc = slack / num_events; - for event in self.event_staging.iter() { - self.writer - .write_all(format!("[timestamp delta: {}]",delta_tc).as_bytes()) - .unwrap(); - self.writer - .write_all(format!(" {}", event).as_bytes()) - .unwrap(); - self.writer.write_all(b"\n").unwrap(); - } - // clear the staged events - self.event_staging.clear(); - // update the current TC - self.curr_tc = timestamp / self.interval; + Entry::Event { + timestamp, + kind: EventKind::SyncStart { .. }, + } => { + self.curr_tc = timestamp / self.interval; + } + Entry::Event { timestamp, kind } => { + if timestamp / self.interval != self.curr_tc { + // smear the timestamps distributing across all events staged, excluding the current event + let slack = (timestamp / self.interval - self.curr_tc) * self.interval; + let num_events = self.event_staging.len() as u64; + let delta_tc = slack / num_events; + for event in self.event_staging.iter() { + self.writer + .write_all(format!("[timestamp delta: {}]", delta_tc).as_bytes()) + .unwrap(); + self.writer + .write_all(format!(" {}", event).as_bytes()) + .unwrap(); + self.writer.write_all(b"\n").unwrap(); + } + // clear the staged events + self.event_staging.clear(); + // update the current TC + self.curr_tc = timestamp / self.interval; + } + self.event_staging.push(kind); } - self.event_staging.push(kind); - } - _ => {} + _ => {} } } diff --git a/src/receivers/txt_receiver.rs b/src/receivers/txt_receiver.rs index c265517..5cb9f3b 100644 --- a/src/receivers/txt_receiver.rs +++ b/src/receivers/txt_receiver.rs @@ -1,5 +1,5 @@ -use crate::receivers::abstract_receiver::{AbstractReceiver, BusReceiver, Shared}; use crate::backend::event::{Entry, EventKind}; +use crate::receivers::abstract_receiver::{AbstractReceiver, BusReceiver, Shared}; use bus::BusReader; use std::fs::File; use std::io::{BufWriter, Write}; @@ -28,7 +28,11 @@ pub fn factory( _config: serde_json::Value, bus_rx: BusReader, ) -> Box { - let path = _config.get("path").and_then(|value| value.as_str()).unwrap_or("trace.txt").to_string(); + let path = _config + .get("path") + .and_then(|value| value.as_str()) + .unwrap_or("trace.txt") + .to_string(); Box::new(TxtReceiver::new(bus_rx, path)) } From 0d07df30917a31ee8ac778666d9cd5ada0108ecc Mon Sep 17 00:00:00 2001 From: Lux Date: Mon, 23 Feb 2026 10:56:51 -0800 Subject: [PATCH 15/24] feat: completed tc and cyc emulation receiver for BB level granularity --- .../baremetal_hello/baremetal_hello_boom.json | 17 ++- src/receivers/cyc_emulation_receiver.rs | 114 ++++++++++++++++++ src/receivers/mod.rs | 2 + src/receivers/tc_emulation_receiver.rs | 5 +- src/receivers/txt_delta_receiver.rs | 72 +++++++++++ 5 files changed, 206 insertions(+), 4 deletions(-) create mode 100644 src/receivers/cyc_emulation_receiver.rs create mode 100644 src/receivers/txt_delta_receiver.rs diff --git a/configs/baremetal_hello/baremetal_hello_boom.json b/configs/baremetal_hello/baremetal_hello_boom.json index ecf8f25..6401767 100644 --- a/configs/baremetal_hello/baremetal_hello_boom.json +++ b/configs/baremetal_hello/baremetal_hello_boom.json @@ -6,6 +6,19 @@ "kernel_jump_label_patch_log": "", "driver_binary_entry_tuples": [], "receivers": { - "txt": { "enabled": true, "path": "trace.trace_hello.txt" } + "txt_delta": { + "enabled": true, + "path": "trace.trace_hello.txt_delta.txt" + }, + "tc_emulation": { + "enabled": true, + "path": "trace.trace_hello.tc_emulation.txt", + "interval": 100 + }, + "cyc_emulation": { + "enabled": true, + "path": "trace.trace_hello.cyc_emulation.txt", + "lim_tnt": 47 + } } -} +} \ No newline at end of file diff --git a/src/receivers/cyc_emulation_receiver.rs b/src/receivers/cyc_emulation_receiver.rs new file mode 100644 index 0000000..9a5469c --- /dev/null +++ b/src/receivers/cyc_emulation_receiver.rs @@ -0,0 +1,114 @@ +use crate::backend::event::{Entry, EventKind}; +use crate::receivers::abstract_receiver::{AbstractReceiver, BusReceiver, Shared}; +use bus::BusReader; +use std::fs::File; +use std::io::{BufWriter, Write}; + +pub struct CycEmulationReceiver { + writer: BufWriter, + receiver: BusReceiver, + curr_cyc: u64, + lim_tnt: u64, + n_tnt: u64, + event_staging: Vec, +} + +/* Emulates the behavior of a CYC-based encoder, used for accuracy analysis + A CYC-based encoder encodes cycles as a property of each trace event. +*/ +impl CycEmulationReceiver { + pub fn new(bus_rx: BusReader, path: String, lim_tnt: u64) -> Self { + Self { + writer: BufWriter::new(File::create(path).unwrap()), + receiver: BusReceiver { + name: "tc_emulation".to_string(), + bus_rx: bus_rx, + checksum: 0, + }, + curr_cyc: 0, + lim_tnt: lim_tnt, + n_tnt: 0, + event_staging: Vec::new(), + } + } +} + +pub fn factory( + _shared: &Shared, + _config: serde_json::Value, + bus_rx: BusReader, +) -> Box { + let path = _config + .get("path") + .and_then(|value| value.as_str()) + .unwrap_or("trace.tc_emulation.txt") + .to_string(); + let lim_tnt = _config + .get("lim_tnt") + .and_then(|value| value.as_u64()) + .unwrap_or(1000000); + Box::new(CycEmulationReceiver::new(bus_rx, path, lim_tnt)) +} + +crate::register_receiver!("cyc_emulation", factory); + +impl AbstractReceiver for CycEmulationReceiver { + fn bus_rx(&mut self) -> &mut BusReader { + &mut self.receiver.bus_rx + } + + fn _bump_checksum(&mut self) { + self.receiver.checksum += 1; + } + + fn _receive_entry(&mut self, entry: Entry) { + match entry { + Entry::Event { timestamp, kind } => { + // first, always stage the event + // this is safe because all events BEFORE a CYC packet is guaranteed to happen beforehand + match kind { + EventKind::SyncStart { .. } => { + self.curr_cyc = timestamp; + } + EventKind::TakenBranch { .. } => { + self.n_tnt += 1; + self.event_staging.push(kind.clone()); + } + EventKind::NonTakenBranch { .. } => { + self.n_tnt += 1; + self.event_staging.push(kind.clone()); + } + _ => { + self.event_staging.push(kind.clone()); + } + } + if self.n_tnt >= self.lim_tnt || matches!(&kind, EventKind::UninferableJump { .. }) + { + // smear the timestamps distributing across all events staged, excluding the current event + let slack = timestamp - self.curr_cyc; + let num_events = self.event_staging.len() as u64; + let delta_cyc = slack / num_events; + for event in self.event_staging.iter() { + self.writer + .write_all(format!("[timestamp delta: {}]", delta_cyc).as_bytes()) + .unwrap(); + self.writer + .write_all(format!(" {}", event).as_bytes()) + .unwrap(); + self.writer.write_all(b"\n").unwrap(); + } + // clear the staged events + self.event_staging.clear(); + self.n_tnt = 0; + // update the current TC + self.curr_cyc = timestamp; + } + } + _ => {} + } + } + + fn _flush(&mut self) { + self.writer.flush().unwrap(); + } +} diff --git a/src/receivers/mod.rs b/src/receivers/mod.rs index 00ce5f7..b2e137b 100644 --- a/src/receivers/mod.rs +++ b/src/receivers/mod.rs @@ -3,11 +3,13 @@ pub mod registry; pub mod stack_unwinder; pub mod bb_stats_receiver; +pub mod cyc_emulation_receiver; pub mod path_profile_receiver; pub mod prv_breakdown_receiver; pub mod speedscope_receiver; pub mod stack_txt_receiver; pub mod tc_emulation_receiver; +pub mod txt_delta_receiver; pub mod txt_receiver; // TODO: mask off for now until verified again diff --git a/src/receivers/tc_emulation_receiver.rs b/src/receivers/tc_emulation_receiver.rs index ae0dd00..5b4d680 100644 --- a/src/receivers/tc_emulation_receiver.rs +++ b/src/receivers/tc_emulation_receiver.rs @@ -70,7 +70,8 @@ impl AbstractReceiver for TcEmulationReceiver { Entry::Event { timestamp, kind } => { if timestamp / self.interval != self.curr_tc { // smear the timestamps distributing across all events staged, excluding the current event - let slack = (timestamp / self.interval - self.curr_tc) * self.interval; + let next_tc = timestamp / self.interval; + let slack = (next_tc - self.curr_tc) * self.interval; let num_events = self.event_staging.len() as u64; let delta_tc = slack / num_events; for event in self.event_staging.iter() { @@ -85,7 +86,7 @@ impl AbstractReceiver for TcEmulationReceiver { // clear the staged events self.event_staging.clear(); // update the current TC - self.curr_tc = timestamp / self.interval; + self.curr_tc = next_tc; } self.event_staging.push(kind); } diff --git a/src/receivers/txt_delta_receiver.rs b/src/receivers/txt_delta_receiver.rs new file mode 100644 index 0000000..9c5cc39 --- /dev/null +++ b/src/receivers/txt_delta_receiver.rs @@ -0,0 +1,72 @@ +use crate::backend::event::{Entry, EventKind}; +use crate::receivers::abstract_receiver::{AbstractReceiver, BusReceiver, Shared}; +use bus::BusReader; +use std::fs::File; +use std::io::{BufWriter, Write}; + +pub struct TxtDeltaReceiver { + writer: BufWriter, + receiver: BusReceiver, + curr_timestamp: u64, +} + +/* Receiver for dumping the trace to a text file */ +impl TxtDeltaReceiver { + pub fn new(bus_rx: BusReader, path: String) -> Self { + Self { + writer: BufWriter::new(File::create(path).unwrap()), + receiver: BusReceiver { + name: "txt".to_string(), + bus_rx: bus_rx, + checksum: 0, + }, + curr_timestamp: 0, + } + } +} + +pub fn factory( + _shared: &Shared, + _config: serde_json::Value, + bus_rx: BusReader, +) -> Box { + let path = _config + .get("path") + .and_then(|value| value.as_str()) + .unwrap_or("trace.txt_delta.txt") + .to_string(); + Box::new(TxtDeltaReceiver::new(bus_rx, path)) +} + +crate::register_receiver!("txt_delta", factory); + +impl AbstractReceiver for TxtDeltaReceiver { + fn bus_rx(&mut self) -> &mut BusReader { + &mut self.receiver.bus_rx + } + + fn _bump_checksum(&mut self) { + self.receiver.checksum += 1; + } + + fn _receive_entry(&mut self, entry: Entry) { + match entry { + Entry::Event { timestamp, kind } => { + self.writer + .write_all(format!("[delta: {}]", timestamp - self.curr_timestamp).as_bytes()) + .unwrap(); + // write the event + self.writer + .write_all(format!(" {}", kind).as_bytes()) + .unwrap(); + self.writer.write_all(b"\n").unwrap(); + self.curr_timestamp = timestamp; + } + _ => {} + } + } + + fn _flush(&mut self) { + self.writer.flush().unwrap(); + } +} From b8eede91a84790d0a63fb96f4b3b09bf6b9a885c Mon Sep 17 00:00:00 2001 From: Lux Date: Mon, 23 Feb 2026 11:35:43 -0800 Subject: [PATCH 16/24] fmt: minor formatting --- configs/baremetal_hello/baremetal_hello_boom.json | 2 +- src/receivers/cyc_emulation_receiver.rs | 7 +++++-- src/receivers/tc_emulation_receiver.rs | 3 +++ 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/configs/baremetal_hello/baremetal_hello_boom.json b/configs/baremetal_hello/baremetal_hello_boom.json index 6401767..2b5df4e 100644 --- a/configs/baremetal_hello/baremetal_hello_boom.json +++ b/configs/baremetal_hello/baremetal_hello_boom.json @@ -13,7 +13,7 @@ "tc_emulation": { "enabled": true, "path": "trace.trace_hello.tc_emulation.txt", - "interval": 100 + "interval": 1000 }, "cyc_emulation": { "enabled": true, diff --git a/src/receivers/cyc_emulation_receiver.rs b/src/receivers/cyc_emulation_receiver.rs index 9a5469c..48a140b 100644 --- a/src/receivers/cyc_emulation_receiver.rs +++ b/src/receivers/cyc_emulation_receiver.rs @@ -82,6 +82,7 @@ impl AbstractReceiver for CycEmulationReceiver { self.event_staging.push(kind.clone()); } } + if self.n_tnt >= self.lim_tnt || matches!(&kind, EventKind::UninferableJump { .. }) { // smear the timestamps distributing across all events staged, excluding the current event @@ -97,10 +98,12 @@ impl AbstractReceiver for CycEmulationReceiver { .unwrap(); self.writer.write_all(b"\n").unwrap(); } - // clear the staged events + + // clear the states self.event_staging.clear(); self.n_tnt = 0; - // update the current TC + + // update the current cycle self.curr_cyc = timestamp; } } diff --git a/src/receivers/tc_emulation_receiver.rs b/src/receivers/tc_emulation_receiver.rs index 5b4d680..bd276bb 100644 --- a/src/receivers/tc_emulation_receiver.rs +++ b/src/receivers/tc_emulation_receiver.rs @@ -67,6 +67,7 @@ impl AbstractReceiver for TcEmulationReceiver { } => { self.curr_tc = timestamp / self.interval; } + Entry::Event { timestamp, kind } => { if timestamp / self.interval != self.curr_tc { // smear the timestamps distributing across all events staged, excluding the current event @@ -83,8 +84,10 @@ impl AbstractReceiver for TcEmulationReceiver { .unwrap(); self.writer.write_all(b"\n").unwrap(); } + // clear the staged events self.event_staging.clear(); + // update the current TC self.curr_tc = next_tc; } From 798daaa329f71e454109649fe8146ea9202ca988 Mon Sep 17 00:00:00 2001 From: Lux Date: Mon, 23 Feb 2026 16:32:00 -0800 Subject: [PATCH 17/24] fix: minor formating --- scripts/analysis/{draw_bb.py => draw_vbb.py} | 0 scripts/analysis/{sort_bb.py => sort_vbb.py} | 0 scripts/analysis/{sort_path.py => sort_vpath.py} | 0 src/receivers/cyc_emulation_receiver.rs | 2 +- src/receivers/tc_emulation_receiver.rs | 2 +- src/receivers/txt_delta_receiver.rs | 6 ++++++ 6 files changed, 8 insertions(+), 2 deletions(-) rename scripts/analysis/{draw_bb.py => draw_vbb.py} (100%) rename scripts/analysis/{sort_bb.py => sort_vbb.py} (100%) rename scripts/analysis/{sort_path.py => sort_vpath.py} (100%) diff --git a/scripts/analysis/draw_bb.py b/scripts/analysis/draw_vbb.py similarity index 100% rename from scripts/analysis/draw_bb.py rename to scripts/analysis/draw_vbb.py diff --git a/scripts/analysis/sort_bb.py b/scripts/analysis/sort_vbb.py similarity index 100% rename from scripts/analysis/sort_bb.py rename to scripts/analysis/sort_vbb.py diff --git a/scripts/analysis/sort_path.py b/scripts/analysis/sort_vpath.py similarity index 100% rename from scripts/analysis/sort_path.py rename to scripts/analysis/sort_vpath.py diff --git a/src/receivers/cyc_emulation_receiver.rs b/src/receivers/cyc_emulation_receiver.rs index 48a140b..85d1ea0 100644 --- a/src/receivers/cyc_emulation_receiver.rs +++ b/src/receivers/cyc_emulation_receiver.rs @@ -91,7 +91,7 @@ impl AbstractReceiver for CycEmulationReceiver { let delta_cyc = slack / num_events; for event in self.event_staging.iter() { self.writer - .write_all(format!("[timestamp delta: {}]", delta_cyc).as_bytes()) + .write_all(format!("[delta: {}]", delta_cyc).as_bytes()) .unwrap(); self.writer .write_all(format!(" {}", event).as_bytes()) diff --git a/src/receivers/tc_emulation_receiver.rs b/src/receivers/tc_emulation_receiver.rs index bd276bb..a593745 100644 --- a/src/receivers/tc_emulation_receiver.rs +++ b/src/receivers/tc_emulation_receiver.rs @@ -77,7 +77,7 @@ impl AbstractReceiver for TcEmulationReceiver { let delta_tc = slack / num_events; for event in self.event_staging.iter() { self.writer - .write_all(format!("[timestamp delta: {}]", delta_tc).as_bytes()) + .write_all(format!("[delta: {}]", delta_tc).as_bytes()) .unwrap(); self.writer .write_all(format!(" {}", event).as_bytes()) diff --git a/src/receivers/txt_delta_receiver.rs b/src/receivers/txt_delta_receiver.rs index 9c5cc39..4923176 100644 --- a/src/receivers/txt_delta_receiver.rs +++ b/src/receivers/txt_delta_receiver.rs @@ -51,6 +51,12 @@ impl AbstractReceiver for TxtDeltaReceiver { fn _receive_entry(&mut self, entry: Entry) { match entry { + Entry::Event { + timestamp, + kind: EventKind::SyncStart { .. }, + } => { + self.curr_timestamp = timestamp; + } Entry::Event { timestamp, kind } => { self.writer .write_all(format!("[delta: {}]", timestamp - self.curr_timestamp).as_bytes()) From aedd8a67721ec4121c7ca3a05c3c4e5b2b744451 Mon Sep 17 00:00:00 2001 From: Lux Date: Tue, 24 Feb 2026 18:08:16 -0800 Subject: [PATCH 18/24] feat: rename to TC and CYC BB emulation receivers and use csv instead of txt --- .../baremetal_hello/baremetal_hello_boom.json | 8 +- configs/embench/baremetal_wikisort.json | 19 +++- scripts/analysis/quantify_bb_error.py | 98 +++++++++++++++++++ src/backend/event.rs | 51 ++++++++++ ...ceiver.rs => cyc_bb_emulation_receiver.rs} | 49 ++++++---- src/receivers/mod.rs | 4 +- ...eceiver.rs => tc_bb_emulation_receiver.rs} | 49 ++++++---- src/receivers/txt_delta_receiver.rs | 14 +-- 8 files changed, 240 insertions(+), 52 deletions(-) create mode 100644 scripts/analysis/quantify_bb_error.py rename src/receivers/{cyc_emulation_receiver.rs => cyc_bb_emulation_receiver.rs} (66%) rename src/receivers/{tc_emulation_receiver.rs => tc_bb_emulation_receiver.rs} (65%) diff --git a/configs/baremetal_hello/baremetal_hello_boom.json b/configs/baremetal_hello/baremetal_hello_boom.json index 2b5df4e..161fdd3 100644 --- a/configs/baremetal_hello/baremetal_hello_boom.json +++ b/configs/baremetal_hello/baremetal_hello_boom.json @@ -10,14 +10,14 @@ "enabled": true, "path": "trace.trace_hello.txt_delta.txt" }, - "tc_emulation": { + "tc_bb_emulation": { "enabled": true, - "path": "trace.trace_hello.tc_emulation.txt", + "path": "trace.trace_hello.tc_bb_emulation.txt", "interval": 1000 }, - "cyc_emulation": { + "cyc_bb_emulation": { "enabled": true, - "path": "trace.trace_hello.cyc_emulation.txt", + "path": "trace.trace_hello.cyc_bb_emulation.txt", "lim_tnt": 47 } } diff --git a/configs/embench/baremetal_wikisort.json b/configs/embench/baremetal_wikisort.json index 47a53ba..4f860e8 100644 --- a/configs/embench/baremetal_wikisort.json +++ b/configs/embench/baremetal_wikisort.json @@ -1,9 +1,24 @@ { - "encoded_trace": "../../sims/vcs/trace_monitor_rockettile_0.encoded.trace", + "encoded_trace": "../../sims/vcs/trace_monitor_boom_tile_0.encoded.trace", "user_binaries": [], "machine_binary": "../baremetal-ide/build/examples/embench/wikisort.elf", "kernel_binary": "", "kernel_jump_label_patch_log": "", "driver_binary_entry_tuples": [], - "receivers": {} + "receivers": { + "txt_delta": { + "enabled": true, + "path": "trace.trace_wikisort.txt_delta.csv" + }, + "tc_bb_emulation": { + "enabled": true, + "path": "trace.trace_wikisort.tc_bb_emulation.csv", + "interval": 1000 + }, + "cyc_bb_emulation": { + "enabled": true, + "path": "trace.trace_wikisort.cyc_bb_emulation.csv", + "lim_tnt": 47 + } + } } diff --git a/scripts/analysis/quantify_bb_error.py b/scripts/analysis/quantify_bb_error.py new file mode 100644 index 0000000..2852121 --- /dev/null +++ b/scripts/analysis/quantify_bb_error.py @@ -0,0 +1,98 @@ +""" +Given two per-basic block delta CSV files, quantify delta error. +""" + +import argparse +import csv + +REQUIRED_COLUMNS = {"delta", "event", "from", "to"} + + +def load_rows(path: str): + rows = [] + with open(path, "r", encoding="utf-8", newline="") as f: + reader = csv.DictReader(f) + if reader.fieldnames is None: + raise ValueError(f"{path}: missing CSV header") + missing = REQUIRED_COLUMNS - set(reader.fieldnames) + if missing: + raise ValueError( + f"{path}: missing required column(s): {', '.join(sorted(missing))}" + ) + + for row_idx, row in enumerate(reader, 2): + event = (row.get("event") or "").strip() + src = (row.get("from") or "").strip() + dst = (row.get("to") or "").strip() + delta_str = (row.get("delta") or "").strip() + if not (event or src or dst or delta_str): + continue + try: + delta = int(delta_str) + except ValueError as exc: + raise ValueError( + f"{path}:{row_idx}: invalid delta value: {delta_str}" + ) from exc + rows.append({"delta": delta, "event": event, "from": src, "to": dst}) + return rows + + +def variance(values): + mean = sum(values) / len(values) + return sum((v - mean) ** 2 for v in values) / len(values) + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("--golden", type=str, required=True) + parser.add_argument("--measured", type=str, required=True) + args = parser.parse_args() + + golden_rows = load_rows(args.golden) + measured_rows = load_rows(args.measured) + + if len(measured_rows) > len(golden_rows): + raise ValueError( + f"Measured has more rows than golden: {len(measured_rows)} > {len(golden_rows)}" + ) + if not measured_rows: + raise ValueError("Measured trace is empty.") + + abs_errors = [] + golden_deltas = [] + measured_deltas = [] + for idx, measured_row in enumerate(measured_rows, 1): + golden_row = golden_rows[idx - 1] + golden_rest = (golden_row["event"], golden_row["from"], golden_row["to"]) + measured_rest = (measured_row["event"], measured_row["from"], measured_row["to"]) + if golden_rest != measured_rest: + raise ValueError( + f"Row {idx} mismatch:\n" + f" golden: event={golden_row['event']}, from={golden_row['from']}, to={golden_row['to']}\n" + f" measured: event={measured_row['event']}, from={measured_row['from']}, to={measured_row['to']}" + ) + abs_errors.append(abs(golden_row["delta"] - measured_row["delta"])) + golden_deltas.append(golden_row["delta"]) + measured_deltas.append(measured_row["delta"]) + + mae = sum(abs_errors) / len(abs_errors) + total_error = sum(abs_errors) + total_time = sum(golden_deltas) + var_golden = variance(golden_deltas) + var_measured = variance(measured_deltas) + var_ratio = float("inf") if var_golden == 0 else var_measured / var_golden + weighted_error = float("inf") if total_time == 0 else total_error / total_time + + print(f"MAE: {mae:.6f}") + if var_ratio == float("inf"): + print("VarRatio: inf") + else: + print(f"VarRatio: {var_ratio:.6f}") + if weighted_error == float("inf"): + print("WeightedError: inf") + else: + print(f"WeightedError: {weighted_error * 100:.4f}%") + + +if __name__ == "__main__": + main() diff --git a/src/backend/event.rs b/src/backend/event.rs index f7c9a4f..77c5a10 100644 --- a/src/backend/event.rs +++ b/src/backend/event.rs @@ -244,3 +244,54 @@ impl std::fmt::Display for EventKind { } } } + +impl EventKind { + pub fn to_csv_string(&self) -> String { + match self { + EventKind::TakenBranch { arc } => { + format!("TB,{:#x},{:#x}", arc.0, arc.1) + } + EventKind::NonTakenBranch { arc } => { + format!("NTB,{:#x},{:#x}", arc.0, arc.1) + } + EventKind::UninferableJump { arc } => { + format!("UJ,{:#x},{:#x}", arc.0, arc.1) + } + EventKind::InferrableJump { arc } => { + format!("IJ,{:#x},{:#x}", arc.0, arc.1) + } + EventKind::Trap { reason, prv_arc: _, arc, ctx: _ } => { + match reason { + TrapReason::Exception => { + format!("TRAP_EXC,{:#x},{:#x}", arc.0, arc.1) + } + TrapReason::Interrupt => { + format!("TRAP_INT,{:#x},{:#x}", arc.0, arc.1) + } + TrapReason::Return => { + format!("TRAP_RET,{:#x},{:#x}", arc.0, arc.1) + } + } + } + EventKind::SyncStart { runtime_cfg: _, start_pc, start_prv: _, start_ctx: _ } => { + format!("SYNC_START,{:#x}, 0x0", start_pc) + } + EventKind::SyncEnd { end_pc } => { + format!("SYNC_END,0x0,{:#x}", end_pc) + } + EventKind::SyncPeriodic => { + format!("SYNC_PERIODIC,0x0,0x0") + } + // EventKind::BPHit { hit_count } => { + // format!("BPHIT,{}", hit_count) + // } + // EventKind::BPMiss => { + // format!("BPMISS") + // } + // EventKind::Panic => { + // format!("PANIC") + // } + _ => panic!("Unsupported event kind: {:?}", self) + } + } +} \ No newline at end of file diff --git a/src/receivers/cyc_emulation_receiver.rs b/src/receivers/cyc_bb_emulation_receiver.rs similarity index 66% rename from src/receivers/cyc_emulation_receiver.rs rename to src/receivers/cyc_bb_emulation_receiver.rs index 85d1ea0..7a79499 100644 --- a/src/receivers/cyc_emulation_receiver.rs +++ b/src/receivers/cyc_bb_emulation_receiver.rs @@ -4,7 +4,7 @@ use bus::BusReader; use std::fs::File; use std::io::{BufWriter, Write}; -pub struct CycEmulationReceiver { +pub struct CycBBEmulationReceiver { writer: BufWriter, receiver: BusReceiver, curr_cyc: u64, @@ -16,10 +16,12 @@ pub struct CycEmulationReceiver { /* Emulates the behavior of a CYC-based encoder, used for accuracy analysis A CYC-based encoder encodes cycles as a property of each trace event. */ -impl CycEmulationReceiver { +impl CycBBEmulationReceiver { pub fn new(bus_rx: BusReader, path: String, lim_tnt: u64) -> Self { + let mut writer = BufWriter::new(File::create(path).unwrap()); + writer.write_all(b"delta,event,from,to\n").unwrap(); Self { - writer: BufWriter::new(File::create(path).unwrap()), + writer: writer, receiver: BusReceiver { name: "tc_emulation".to_string(), bus_rx: bus_rx, @@ -41,18 +43,18 @@ pub fn factory( let path = _config .get("path") .and_then(|value| value.as_str()) - .unwrap_or("trace.tc_emulation.txt") + .unwrap_or("trace.tc_emulation.csv") .to_string(); let lim_tnt = _config .get("lim_tnt") .and_then(|value| value.as_u64()) .unwrap_or(1000000); - Box::new(CycEmulationReceiver::new(bus_rx, path, lim_tnt)) + Box::new(CycBBEmulationReceiver::new(bus_rx, path, lim_tnt)) } -crate::register_receiver!("cyc_emulation", factory); +crate::register_receiver!("cyc_bb_emulation", factory); -impl AbstractReceiver for CycEmulationReceiver { +impl AbstractReceiver for CycBBEmulationReceiver { fn bus_rx(&mut self) -> &mut BusReader { &mut self.receiver.bus_rx } @@ -89,19 +91,30 @@ impl AbstractReceiver for CycEmulationReceiver { let slack = timestamp - self.curr_cyc; let num_events = self.event_staging.len() as u64; let delta_cyc = slack / num_events; - for event in self.event_staging.iter() { - self.writer - .write_all(format!("[delta: {}]", delta_cyc).as_bytes()) - .unwrap(); + + if num_events > 0 { + // the last events gets the remainder as well + let last_event = self.event_staging.pop().unwrap(); + + for event in self.event_staging.iter() { + self.writer + .write_all(format!("{},{}", delta_cyc, event.to_csv_string()).as_bytes()) + .unwrap(); + // self.writer + // .write_all(format!(" {}", event).as_bytes()) + // .unwrap(); + self.writer.write_all(b"\n").unwrap(); + } + + // write the last event self.writer - .write_all(format!(" {}", event).as_bytes()) - .unwrap(); - self.writer.write_all(b"\n").unwrap(); - } + .write_all(format!("{},{}\n", delta_cyc + slack % num_events, last_event.to_csv_string()).as_bytes()) + .unwrap(); - // clear the states - self.event_staging.clear(); - self.n_tnt = 0; + // clear the states + self.event_staging.clear(); + self.n_tnt = 0; + } // update the current cycle self.curr_cyc = timestamp; diff --git a/src/receivers/mod.rs b/src/receivers/mod.rs index b2e137b..4f3f52e 100644 --- a/src/receivers/mod.rs +++ b/src/receivers/mod.rs @@ -3,12 +3,12 @@ pub mod registry; pub mod stack_unwinder; pub mod bb_stats_receiver; -pub mod cyc_emulation_receiver; +pub mod cyc_bb_emulation_receiver; pub mod path_profile_receiver; pub mod prv_breakdown_receiver; pub mod speedscope_receiver; pub mod stack_txt_receiver; -pub mod tc_emulation_receiver; +pub mod tc_bb_emulation_receiver; pub mod txt_delta_receiver; pub mod txt_receiver; diff --git a/src/receivers/tc_emulation_receiver.rs b/src/receivers/tc_bb_emulation_receiver.rs similarity index 65% rename from src/receivers/tc_emulation_receiver.rs rename to src/receivers/tc_bb_emulation_receiver.rs index a593745..1675380 100644 --- a/src/receivers/tc_emulation_receiver.rs +++ b/src/receivers/tc_bb_emulation_receiver.rs @@ -4,7 +4,7 @@ use bus::BusReader; use std::fs::File; use std::io::{BufWriter, Write}; -pub struct TcEmulationReceiver { +pub struct TcBBEmulationReceiver { writer: BufWriter, receiver: BusReceiver, curr_tc: u64, @@ -15,10 +15,12 @@ pub struct TcEmulationReceiver { /* Emulates the behavior of a TC-based encoder, used for accuracy analysis A TC-based encoder encodes timestamp as separate packets emitted in fixed intervals. */ -impl TcEmulationReceiver { +impl TcBBEmulationReceiver { pub fn new(bus_rx: BusReader, path: String, interval: u64) -> Self { + let mut writer = BufWriter::new(File::create(path).unwrap()); + writer.write_all(b"delta,event,from,to\n").unwrap(); Self { - writer: BufWriter::new(File::create(path).unwrap()), + writer: writer, receiver: BusReceiver { name: "tc_emulation".to_string(), bus_rx: bus_rx, @@ -39,18 +41,18 @@ pub fn factory( let path = _config .get("path") .and_then(|value| value.as_str()) - .unwrap_or("trace.tc_emulation.txt") + .unwrap_or("trace.tc_bb_emulation.csv") .to_string(); let interval = _config .get("interval") .and_then(|value| value.as_u64()) .unwrap_or(1000000); - Box::new(TcEmulationReceiver::new(bus_rx, path, interval)) + Box::new(TcBBEmulationReceiver::new(bus_rx, path, interval)) } -crate::register_receiver!("tc_emulation", factory); +crate::register_receiver!("tc_bb_emulation", factory); -impl AbstractReceiver for TcEmulationReceiver { +impl AbstractReceiver for TcBBEmulationReceiver { fn bus_rx(&mut self) -> &mut BusReader { &mut self.receiver.bus_rx } @@ -75,21 +77,28 @@ impl AbstractReceiver for TcEmulationReceiver { let slack = (next_tc - self.curr_tc) * self.interval; let num_events = self.event_staging.len() as u64; let delta_tc = slack / num_events; - for event in self.event_staging.iter() { - self.writer - .write_all(format!("[delta: {}]", delta_tc).as_bytes()) - .unwrap(); + + self.curr_tc = next_tc; + + if num_events > 0 { + // the last events gets the remainder as well + let last_event = self.event_staging.pop().unwrap(); + + // write the remaining events + for event in self.event_staging.iter() { + self.writer + .write_all(format!("{},{}\n", delta_tc, event.to_csv_string()).as_bytes()) + .unwrap(); + } + + // write the last event self.writer - .write_all(format!(" {}", event).as_bytes()) - .unwrap(); - self.writer.write_all(b"\n").unwrap(); - } - - // clear the staged events - self.event_staging.clear(); + .write_all(format!("{},{}\n", delta_tc + slack % num_events, last_event.to_csv_string()).as_bytes()) + .unwrap(); - // update the current TC - self.curr_tc = next_tc; + // clear the staged events + self.event_staging.clear(); + } } self.event_staging.push(kind); } diff --git a/src/receivers/txt_delta_receiver.rs b/src/receivers/txt_delta_receiver.rs index 4923176..e9459ab 100644 --- a/src/receivers/txt_delta_receiver.rs +++ b/src/receivers/txt_delta_receiver.rs @@ -13,8 +13,10 @@ pub struct TxtDeltaReceiver { /* Receiver for dumping the trace to a text file */ impl TxtDeltaReceiver { pub fn new(bus_rx: BusReader, path: String) -> Self { + let mut writer = BufWriter::new(File::create(path).unwrap()); + writer.write_all(b"delta,event,from,to\n").unwrap(); Self { - writer: BufWriter::new(File::create(path).unwrap()), + writer: writer, receiver: BusReceiver { name: "txt".to_string(), bus_rx: bus_rx, @@ -33,7 +35,7 @@ pub fn factory( let path = _config .get("path") .and_then(|value| value.as_str()) - .unwrap_or("trace.txt_delta.txt") + .unwrap_or("trace.tacit_delta.csv") .to_string(); Box::new(TxtDeltaReceiver::new(bus_rx, path)) } @@ -59,12 +61,12 @@ impl AbstractReceiver for TxtDeltaReceiver { } Entry::Event { timestamp, kind } => { self.writer - .write_all(format!("[delta: {}]", timestamp - self.curr_timestamp).as_bytes()) + .write_all(format!("{},{}", timestamp - self.curr_timestamp, kind.to_csv_string()).as_bytes()) .unwrap(); // write the event - self.writer - .write_all(format!(" {}", kind).as_bytes()) - .unwrap(); + // self.writer + // .write_all(format!(" {}", kind).as_bytes()) + // .unwrap(); self.writer.write_all(b"\n").unwrap(); self.curr_timestamp = timestamp; } From a9cbc4767e3b2c67f1953aa26e95f69f74c6143a Mon Sep 17 00:00:00 2001 From: Lux Date: Thu, 26 Feb 2026 15:06:31 -0800 Subject: [PATCH 19/24] refactor: reorganized the receivers --- configs/embench/baremetal_wikisort.json | 15 +- scripts/analysis/quantify_bb_error.py | 18 +- .../{ => analysis}/bb_stats_receiver.rs | 0 .../{ => analysis}/path_profile_receiver.rs | 0 .../{ => analysis}/prv_breakdown_receiver.rs | 0 .../{ => analysis}/speedscope_receiver.rs | 0 .../{ => analysis}/stack_txt_receiver.rs | 0 .../{ => analysis}/txt_delta_receiver.rs | 0 src/receivers/{ => analysis}/txt_receiver.rs | 0 src/receivers/{ => core}/abstract_receiver.rs | 0 src/receivers/{ => core}/registry.rs | 0 src/receivers/{ => core}/stack_unwinder.rs | 0 .../cyc_bb_emulation_receiver.rs | 4 +- .../emulation/cyc_func_emulation_receiver.rs | 160 ++++++++++++++++++ .../emulation/reference_bb_receiver.rs | 80 +++++++++ .../emulation/reference_func_receiver.rs | 93 ++++++++++ .../tc_bb_emulation_receiver.rs | 0 .../{ => experimental}/afdo_receiver.rs | 0 .../{ => experimental}/atomic_receiver.rs | 0 .../{ => experimental}/gcda_receiver.rs | 0 .../{ => experimental}/perfetto_receiver.rs | 0 src/receivers/mod.rs | 31 +++- 22 files changed, 382 insertions(+), 19 deletions(-) rename src/receivers/{ => analysis}/bb_stats_receiver.rs (100%) rename src/receivers/{ => analysis}/path_profile_receiver.rs (100%) rename src/receivers/{ => analysis}/prv_breakdown_receiver.rs (100%) rename src/receivers/{ => analysis}/speedscope_receiver.rs (100%) rename src/receivers/{ => analysis}/stack_txt_receiver.rs (100%) rename src/receivers/{ => analysis}/txt_delta_receiver.rs (100%) rename src/receivers/{ => analysis}/txt_receiver.rs (100%) rename src/receivers/{ => core}/abstract_receiver.rs (100%) rename src/receivers/{ => core}/registry.rs (100%) rename src/receivers/{ => core}/stack_unwinder.rs (100%) rename src/receivers/{ => emulation}/cyc_bb_emulation_receiver.rs (97%) create mode 100644 src/receivers/emulation/cyc_func_emulation_receiver.rs create mode 100644 src/receivers/emulation/reference_bb_receiver.rs create mode 100644 src/receivers/emulation/reference_func_receiver.rs rename src/receivers/{ => emulation}/tc_bb_emulation_receiver.rs (100%) rename src/receivers/{ => experimental}/afdo_receiver.rs (100%) rename src/receivers/{ => experimental}/atomic_receiver.rs (100%) rename src/receivers/{ => experimental}/gcda_receiver.rs (100%) rename src/receivers/{ => experimental}/perfetto_receiver.rs (100%) diff --git a/configs/embench/baremetal_wikisort.json b/configs/embench/baremetal_wikisort.json index 4f860e8..0052d4e 100644 --- a/configs/embench/baremetal_wikisort.json +++ b/configs/embench/baremetal_wikisort.json @@ -6,9 +6,13 @@ "kernel_jump_label_patch_log": "", "driver_binary_entry_tuples": [], "receivers": { - "txt_delta": { + "reference_bb": { "enabled": true, - "path": "trace.trace_wikisort.txt_delta.csv" + "path": "trace.trace_wikisort.reference_bb.csv" + }, + "reference_func": { + "enabled": true, + "path": "trace.trace_wikisort.reference_func.csv" }, "tc_bb_emulation": { "enabled": true, @@ -18,7 +22,12 @@ "cyc_bb_emulation": { "enabled": true, "path": "trace.trace_wikisort.cyc_bb_emulation.csv", - "lim_tnt": 47 + "lim_tnt": 6 + }, + "cyc_func_emulation": { + "enabled": true, + "path": "trace.trace_wikisort.cyc_func_emulation.csv", + "lim_tnt": 6 } } } diff --git a/scripts/analysis/quantify_bb_error.py b/scripts/analysis/quantify_bb_error.py index 2852121..9476266 100644 --- a/scripts/analysis/quantify_bb_error.py +++ b/scripts/analysis/quantify_bb_error.py @@ -5,7 +5,7 @@ import argparse import csv -REQUIRED_COLUMNS = {"delta", "event", "from", "to"} +REQUIRED_COLUMNS = {"delta", "event"} def load_rows(path: str): @@ -22,18 +22,16 @@ def load_rows(path: str): for row_idx, row in enumerate(reader, 2): event = (row.get("event") or "").strip() - src = (row.get("from") or "").strip() - dst = (row.get("to") or "").strip() + # src = (row.get("from") or "").strip() + # dst = (row.get("to") or "").strip() delta_str = (row.get("delta") or "").strip() - if not (event or src or dst or delta_str): - continue try: delta = int(delta_str) except ValueError as exc: raise ValueError( f"{path}:{row_idx}: invalid delta value: {delta_str}" ) from exc - rows.append({"delta": delta, "event": event, "from": src, "to": dst}) + rows.append({"delta": delta, "event": event}) return rows @@ -63,13 +61,11 @@ def main(): measured_deltas = [] for idx, measured_row in enumerate(measured_rows, 1): golden_row = golden_rows[idx - 1] - golden_rest = (golden_row["event"], golden_row["from"], golden_row["to"]) - measured_rest = (measured_row["event"], measured_row["from"], measured_row["to"]) + golden_rest = (golden_row["event"]) + measured_rest = (measured_row["event"]) if golden_rest != measured_rest: raise ValueError( - f"Row {idx} mismatch:\n" - f" golden: event={golden_row['event']}, from={golden_row['from']}, to={golden_row['to']}\n" - f" measured: event={measured_row['event']}, from={measured_row['from']}, to={measured_row['to']}" + f"Row {idx} mismatch: golden={golden_rest}, measured={measured_rest}" ) abs_errors.append(abs(golden_row["delta"] - measured_row["delta"])) golden_deltas.append(golden_row["delta"]) diff --git a/src/receivers/bb_stats_receiver.rs b/src/receivers/analysis/bb_stats_receiver.rs similarity index 100% rename from src/receivers/bb_stats_receiver.rs rename to src/receivers/analysis/bb_stats_receiver.rs diff --git a/src/receivers/path_profile_receiver.rs b/src/receivers/analysis/path_profile_receiver.rs similarity index 100% rename from src/receivers/path_profile_receiver.rs rename to src/receivers/analysis/path_profile_receiver.rs diff --git a/src/receivers/prv_breakdown_receiver.rs b/src/receivers/analysis/prv_breakdown_receiver.rs similarity index 100% rename from src/receivers/prv_breakdown_receiver.rs rename to src/receivers/analysis/prv_breakdown_receiver.rs diff --git a/src/receivers/speedscope_receiver.rs b/src/receivers/analysis/speedscope_receiver.rs similarity index 100% rename from src/receivers/speedscope_receiver.rs rename to src/receivers/analysis/speedscope_receiver.rs diff --git a/src/receivers/stack_txt_receiver.rs b/src/receivers/analysis/stack_txt_receiver.rs similarity index 100% rename from src/receivers/stack_txt_receiver.rs rename to src/receivers/analysis/stack_txt_receiver.rs diff --git a/src/receivers/txt_delta_receiver.rs b/src/receivers/analysis/txt_delta_receiver.rs similarity index 100% rename from src/receivers/txt_delta_receiver.rs rename to src/receivers/analysis/txt_delta_receiver.rs diff --git a/src/receivers/txt_receiver.rs b/src/receivers/analysis/txt_receiver.rs similarity index 100% rename from src/receivers/txt_receiver.rs rename to src/receivers/analysis/txt_receiver.rs diff --git a/src/receivers/abstract_receiver.rs b/src/receivers/core/abstract_receiver.rs similarity index 100% rename from src/receivers/abstract_receiver.rs rename to src/receivers/core/abstract_receiver.rs diff --git a/src/receivers/registry.rs b/src/receivers/core/registry.rs similarity index 100% rename from src/receivers/registry.rs rename to src/receivers/core/registry.rs diff --git a/src/receivers/stack_unwinder.rs b/src/receivers/core/stack_unwinder.rs similarity index 100% rename from src/receivers/stack_unwinder.rs rename to src/receivers/core/stack_unwinder.rs diff --git a/src/receivers/cyc_bb_emulation_receiver.rs b/src/receivers/emulation/cyc_bb_emulation_receiver.rs similarity index 97% rename from src/receivers/cyc_bb_emulation_receiver.rs rename to src/receivers/emulation/cyc_bb_emulation_receiver.rs index 7a79499..f3d1ecd 100644 --- a/src/receivers/cyc_bb_emulation_receiver.rs +++ b/src/receivers/emulation/cyc_bb_emulation_receiver.rs @@ -23,7 +23,7 @@ impl CycBBEmulationReceiver { Self { writer: writer, receiver: BusReceiver { - name: "tc_emulation".to_string(), + name: "cyc_bb_emulation".to_string(), bus_rx: bus_rx, checksum: 0, }, @@ -43,7 +43,7 @@ pub fn factory( let path = _config .get("path") .and_then(|value| value.as_str()) - .unwrap_or("trace.tc_emulation.csv") + .unwrap_or("trace.cyc_bb_emulation.csv") .to_string(); let lim_tnt = _config .get("lim_tnt") diff --git a/src/receivers/emulation/cyc_func_emulation_receiver.rs b/src/receivers/emulation/cyc_func_emulation_receiver.rs new file mode 100644 index 0000000..15e6c2f --- /dev/null +++ b/src/receivers/emulation/cyc_func_emulation_receiver.rs @@ -0,0 +1,160 @@ +use crate::backend::event::{Entry, EventKind}; +use crate::receivers::abstract_receiver::{AbstractReceiver, BusReceiver, Shared}; +use bus::BusReader; +use std::fs::File; +use std::io::{BufWriter, Write}; +use crate::receivers::stack_unwinder::StackUnwinder; +use crate::common::symbol_index::SymbolIndex; +use std::sync::Arc; + +pub struct CycFuncEmulationReceiver { + writer: BufWriter, + receiver: BusReceiver, + curr_cyc: u64, + lim_tnt: u64, + n_tnt: u64, + event_staging: Vec, + unwinder: StackUnwinder, + func_entry_time_stack: Vec, +} + +/* Emulates the behavior of a CYC-based encoder, used for accuracy analysis + A CYC-based encoder encodes cycles as a property of each trace event. +*/ +impl CycFuncEmulationReceiver { + pub fn new(bus_rx: BusReader, symbols: Arc, path: String, lim_tnt: u64) -> Self { + let unwinder = StackUnwinder::new(symbols).expect("init unwinder"); + let mut writer = BufWriter::new(File::create(path).unwrap()); + writer.write_all(b"delta,event\n").unwrap(); + Self { + writer: writer, + receiver: BusReceiver { + name: "cyc_func_emulation".to_string(), + bus_rx: bus_rx, + checksum: 0, + }, + curr_cyc: 0, + lim_tnt: lim_tnt, + n_tnt: 0, + event_staging: Vec::new(), + unwinder, + func_entry_time_stack: Vec::new(), + } + } +} + +pub fn factory( + _shared: &Shared, + _config: serde_json::Value, + bus_rx: BusReader, +) -> Box { + let path = _config + .get("path") + .and_then(|value| value.as_str()) + .unwrap_or("trace.cyc_func_emulation.csv") + .to_string(); + let lim_tnt = _config + .get("lim_tnt") + .and_then(|value| value.as_u64()) + .unwrap_or(1000000); + Box::new(CycFuncEmulationReceiver::new(bus_rx, Arc::clone(&_shared.symbol_index), path, lim_tnt)) +} + +crate::register_receiver!("cyc_func_emulation", factory); + +impl AbstractReceiver for CycFuncEmulationReceiver { + fn bus_rx(&mut self) -> &mut BusReader { + &mut self.receiver.bus_rx + } + + fn _bump_checksum(&mut self) { + self.receiver.checksum += 1; + } + + fn _receive_entry(&mut self, entry: Entry) { + match entry { + Entry::Event { timestamp, kind } => { + // first, always stage the event + // this is safe because all events BEFORE a CYC packet is guaranteed to happen beforehand + match kind { + EventKind::SyncStart { .. } => { + self.curr_cyc = timestamp; + } + EventKind::TakenBranch { .. } => { + self.n_tnt += 1; + self.event_staging.push(kind.clone()); + } + EventKind::NonTakenBranch { .. } => { + self.n_tnt += 1; + self.event_staging.push(kind.clone()); + } + _ => { + self.event_staging.push(kind.clone()); + } + } + + if self.n_tnt >= self.lim_tnt || matches!(&kind, EventKind::UninferableJump { .. }) + { + // smear the timestamps distributing across all events staged, excluding the current event + let slack = timestamp - self.curr_cyc; + let num_events = self.event_staging.len() as u64; + let delta_cyc = slack / num_events; + + if num_events > 0 { + // the last events gets the remainder as well + let last_event = self.event_staging.pop().unwrap(); + + for event in self.event_staging.iter() { + self.curr_cyc += delta_cyc; + if let Some(update) = self.unwinder.step(&Entry::Event { timestamp: self.curr_cyc, kind: event.clone() }) { + for frame in update.frames_closed { + // pop the func_entry_time_stack + let func_entry_time = self.func_entry_time_stack.pop().unwrap(); + let delta_time = self.curr_cyc - func_entry_time; + self.writer + .write_all(format!("{},{}", delta_time, frame.symbol.name).as_bytes()) + .unwrap(); + self.writer.write_all(b"\n").unwrap(); + } + if let Some(_) = update.frames_opened { + // push the current cycle to the func_entry_time_stack + self.func_entry_time_stack.push(self.curr_cyc); + } + } + } + + // handle the last event + self.curr_cyc += delta_cyc + slack % num_events; + assert_eq!(self.curr_cyc, timestamp); + if let Some(update) = self.unwinder.step(&Entry::Event { timestamp: timestamp, kind: last_event.clone() }) { + for frame in update.frames_closed { + // pop the func_entry_time_stack + let func_entry_time = self.func_entry_time_stack.pop().unwrap(); + let delta_time = self.curr_cyc - func_entry_time; + self.writer + .write_all(format!("{},{}", delta_time, frame.symbol.name).as_bytes()) + .unwrap(); + self.writer.write_all(b"\n").unwrap(); + } + if let Some(_) = update.frames_opened { + // push the current cycle to the func_entry_time_stack + self.func_entry_time_stack.push(self.curr_cyc); + } + } + // clear the states + self.event_staging.clear(); + self.n_tnt = 0; + } + + // update the current cycle + self.curr_cyc = timestamp; + } + } + _ => {} + } + } + + fn _flush(&mut self) { + self.writer.flush().unwrap(); + } +} diff --git a/src/receivers/emulation/reference_bb_receiver.rs b/src/receivers/emulation/reference_bb_receiver.rs new file mode 100644 index 0000000..b69478e --- /dev/null +++ b/src/receivers/emulation/reference_bb_receiver.rs @@ -0,0 +1,80 @@ +use crate::backend::event::{Entry, EventKind}; +use crate::receivers::abstract_receiver::{AbstractReceiver, BusReceiver, Shared}; +use bus::BusReader; +use std::fs::File; +use std::io::{BufWriter, Write}; + +pub struct ReferenceBBReceiver { + writer: BufWriter, + receiver: BusReceiver, + curr_timestamp: u64, +} + +/* Receiver for dumping the trace to a text file */ +impl ReferenceBBReceiver { + pub fn new(bus_rx: BusReader, path: String) -> Self { + let mut writer = BufWriter::new(File::create(path).unwrap()); + writer.write_all(b"delta,event,from,to\n").unwrap(); + Self { + writer: writer, + receiver: BusReceiver { + name: "reference_bb".to_string(), + bus_rx: bus_rx, + checksum: 0, + }, + curr_timestamp: 0, + } + } +} + +pub fn factory( + _shared: &Shared, + _config: serde_json::Value, + bus_rx: BusReader, +) -> Box { + let path = _config + .get("path") + .and_then(|value| value.as_str()) + .unwrap_or("trace.reference_bb.csv") + .to_string(); + Box::new(ReferenceBBReceiver::new(bus_rx, path)) +} + +crate::register_receiver!("reference_bb", factory); + +impl AbstractReceiver for ReferenceBBReceiver { + fn bus_rx(&mut self) -> &mut BusReader { + &mut self.receiver.bus_rx + } + + fn _bump_checksum(&mut self) { + self.receiver.checksum += 1; + } + + fn _receive_entry(&mut self, entry: Entry) { + match entry { + Entry::Event { + timestamp, + kind: EventKind::SyncStart { .. }, + } => { + self.curr_timestamp = timestamp; + } + Entry::Event { timestamp, kind } => { + self.writer + .write_all(format!("{},{}", timestamp - self.curr_timestamp, kind.to_csv_string()).as_bytes()) + .unwrap(); + // write the event + // self.writer + // .write_all(format!(" {}", kind).as_bytes()) + // .unwrap(); + self.writer.write_all(b"\n").unwrap(); + self.curr_timestamp = timestamp; + } + _ => {} + } + } + + fn _flush(&mut self) { + self.writer.flush().unwrap(); + } +} diff --git a/src/receivers/emulation/reference_func_receiver.rs b/src/receivers/emulation/reference_func_receiver.rs new file mode 100644 index 0000000..c55beee --- /dev/null +++ b/src/receivers/emulation/reference_func_receiver.rs @@ -0,0 +1,93 @@ +use crate::backend::event::{Entry, EventKind}; +use crate::receivers::abstract_receiver::{AbstractReceiver, BusReceiver, Shared}; +use bus::BusReader; +use std::fs::File; +use std::io::{BufWriter, Write}; +use crate::receivers::stack_unwinder::StackUnwinder; +use crate::common::symbol_index::SymbolIndex; +use std::sync::Arc; + +pub struct ReferenceFuncReceiver { + writer: BufWriter, + receiver: BusReceiver, + curr_timestamp: u64, + unwinder: StackUnwinder, + func_entry_time_stack: Vec, +} + +/* Receiver for dumping the trace to a text file */ +impl ReferenceFuncReceiver { + pub fn new(bus_rx: BusReader, symbols: Arc, path: String) -> Self { + let unwinder = StackUnwinder::new(symbols).expect("init unwinder"); + let mut writer = BufWriter::new(File::create(path).unwrap()); + writer.write_all(b"delta,event\n").unwrap(); + Self { + writer: writer, + receiver: BusReceiver { + name: "reference_func".to_string(), + bus_rx: bus_rx, + checksum: 0, + }, + curr_timestamp: 0, + unwinder, + func_entry_time_stack: Vec::new(), + } + } +} + +pub fn factory( + _shared: &Shared, + _config: serde_json::Value, + bus_rx: BusReader, +) -> Box { + let path = _config + .get("path") + .and_then(|value| value.as_str()) + .unwrap_or("trace.reference_func.csv") + .to_string(); + Box::new(ReferenceFuncReceiver::new(bus_rx, Arc::clone(&_shared.symbol_index), path)) +} + +crate::register_receiver!("reference_func", factory); + +impl AbstractReceiver for ReferenceFuncReceiver { + fn bus_rx(&mut self) -> &mut BusReader { + &mut self.receiver.bus_rx + } + + fn _bump_checksum(&mut self) { + self.receiver.checksum += 1; + } + + fn _receive_entry(&mut self, entry: Entry) { + match entry { + Entry::Event { + timestamp, + kind: EventKind::SyncStart { .. }, + } => { + self.curr_timestamp = timestamp; + } + Entry::Event { timestamp, kind } => { + self.curr_timestamp = timestamp; + if let Some(update) = self.unwinder.step(&Entry::Event { timestamp, kind }) { + for frame in update.frames_closed { + let func_entry_time = self.func_entry_time_stack.pop().unwrap(); + let delta_time = timestamp - func_entry_time; + self.writer + .write_all(format!("{},{}\n", delta_time, frame.symbol.name).as_bytes()) + .unwrap(); + } + + if let Some(_) = update.frames_opened { + self.func_entry_time_stack.push(timestamp); + } + } + } + _ => {} + } + } + + fn _flush(&mut self) { + self.writer.flush().unwrap(); + } +} diff --git a/src/receivers/tc_bb_emulation_receiver.rs b/src/receivers/emulation/tc_bb_emulation_receiver.rs similarity index 100% rename from src/receivers/tc_bb_emulation_receiver.rs rename to src/receivers/emulation/tc_bb_emulation_receiver.rs diff --git a/src/receivers/afdo_receiver.rs b/src/receivers/experimental/afdo_receiver.rs similarity index 100% rename from src/receivers/afdo_receiver.rs rename to src/receivers/experimental/afdo_receiver.rs diff --git a/src/receivers/atomic_receiver.rs b/src/receivers/experimental/atomic_receiver.rs similarity index 100% rename from src/receivers/atomic_receiver.rs rename to src/receivers/experimental/atomic_receiver.rs diff --git a/src/receivers/gcda_receiver.rs b/src/receivers/experimental/gcda_receiver.rs similarity index 100% rename from src/receivers/gcda_receiver.rs rename to src/receivers/experimental/gcda_receiver.rs diff --git a/src/receivers/perfetto_receiver.rs b/src/receivers/experimental/perfetto_receiver.rs similarity index 100% rename from src/receivers/perfetto_receiver.rs rename to src/receivers/experimental/perfetto_receiver.rs diff --git a/src/receivers/mod.rs b/src/receivers/mod.rs index 4f3f52e..57b0d13 100644 --- a/src/receivers/mod.rs +++ b/src/receivers/mod.rs @@ -1,19 +1,44 @@ +#[path = "core/abstract_receiver.rs"] pub mod abstract_receiver; +#[path = "core/registry.rs"] pub mod registry; +#[path = "core/stack_unwinder.rs"] pub mod stack_unwinder; +#[path = "analysis/bb_stats_receiver.rs"] pub mod bb_stats_receiver; -pub mod cyc_bb_emulation_receiver; +#[path = "analysis/path_profile_receiver.rs"] pub mod path_profile_receiver; +#[path = "analysis/prv_breakdown_receiver.rs"] pub mod prv_breakdown_receiver; +#[path = "analysis/speedscope_receiver.rs"] pub mod speedscope_receiver; +#[path = "analysis/stack_txt_receiver.rs"] pub mod stack_txt_receiver; -pub mod tc_bb_emulation_receiver; -pub mod txt_delta_receiver; +// #[path = "analysis/txt_delta_receiver.rs"] +// pub mod txt_delta_receiver; +#[path = "analysis/txt_receiver.rs"] pub mod txt_receiver; +#[path = "emulation/cyc_bb_emulation_receiver.rs"] +pub mod cyc_bb_emulation_receiver; +#[path = "emulation/tc_bb_emulation_receiver.rs"] +pub mod tc_bb_emulation_receiver; +#[path = "emulation/cyc_func_emulation_receiver.rs"] +pub mod cyc_func_emulation_receiver; +// pub mod tc_func_emulation_receiver; + +#[path = "emulation/reference_bb_receiver.rs"] +pub mod reference_bb_receiver; +#[path = "emulation/reference_func_receiver.rs"] +pub mod reference_func_receiver; + // TODO: mask off for now until verified again +// #[path = "experimental/afdo_receiver.rs"] // pub mod afdo_receiver; +// #[path = "experimental/gcda_receiver.rs"] // pub mod gcda_receiver; +// #[path = "experimental/atomic_receiver.rs"] // pub mod atomic_receiver; +// #[path = "experimental/perfetto_receiver.rs"] // pub mod perfetto_receiver; From 0c14a07b856070759b1373487f2c81ce8005d938 Mon Sep 17 00:00:00 2001 From: Lux Date: Fri, 27 Feb 2026 12:17:57 -0800 Subject: [PATCH 20/24] stage: func emulation, trying a different implementation --- configs/embench/baremetal_huffbench.json | 32 +++++++++++++++++-- configs/embench/baremetal_wikisort.json | 14 +++++--- ...quantify_bb_error.py => quantify_error.py} | 2 ++ .../emulation/cyc_func_emulation_receiver.rs | 4 +-- .../emulation/reference_func_receiver.rs | 2 +- 5 files changed, 44 insertions(+), 10 deletions(-) rename scripts/analysis/{quantify_bb_error.py => quantify_error.py} (97%) diff --git a/configs/embench/baremetal_huffbench.json b/configs/embench/baremetal_huffbench.json index 755e41e..1c280ae 100644 --- a/configs/embench/baremetal_huffbench.json +++ b/configs/embench/baremetal_huffbench.json @@ -1,9 +1,37 @@ { - "encoded_trace": "../../sims/vcs/trace_monitor_rockettile_0.encoded.trace", + "encoded_trace": "../../sims/vcs/trace_monitor_boom_tile_0.encoded.trace", "user_binaries": [], "machine_binary": "../baremetal-ide/build/examples/embench/huffbench.elf", "kernel_binary": "", "kernel_jump_label_patch_log": "", "driver_binary_entry_tuples": [], - "receivers": {} + "receivers": { + "reference_bb": { + "enabled": true, + "path": "trace.trace_huffbench.reference_bb.csv" + }, + "reference_func": { + "enabled": true, + "path": "trace.trace_huffbench.reference_func.csv" + }, + "tc_bb_emulation": { + "enabled": true, + "path": "trace.trace_huffbench.tc_bb_emulation.csv", + "interval": 1000 + }, + "cyc_bb_emulation": { + "enabled": true, + "path": "trace.trace_huffbench.cyc_bb_emulation.csv", + "lim_tnt": 47 + }, + "cyc_func_emulation": { + "enabled": true, + "path": "trace.trace_huffbench.cyc_func_emulation.csv", + "lim_tnt": 47 + }, + "speedscope": { + "enabled": true, + "path": "trace.trace_huffbench.speedscope.json" + } + } } diff --git a/configs/embench/baremetal_wikisort.json b/configs/embench/baremetal_wikisort.json index 0052d4e..9676ced 100644 --- a/configs/embench/baremetal_wikisort.json +++ b/configs/embench/baremetal_wikisort.json @@ -7,27 +7,31 @@ "driver_binary_entry_tuples": [], "receivers": { "reference_bb": { - "enabled": true, + "enabled": false, "path": "trace.trace_wikisort.reference_bb.csv" }, "reference_func": { - "enabled": true, + "enabled": false, "path": "trace.trace_wikisort.reference_func.csv" }, "tc_bb_emulation": { - "enabled": true, + "enabled": false, "path": "trace.trace_wikisort.tc_bb_emulation.csv", "interval": 1000 }, "cyc_bb_emulation": { - "enabled": true, + "enabled": false, "path": "trace.trace_wikisort.cyc_bb_emulation.csv", "lim_tnt": 6 }, "cyc_func_emulation": { - "enabled": true, + "enabled": false, "path": "trace.trace_wikisort.cyc_func_emulation.csv", "lim_tnt": 6 + }, + "speedscope": { + "enabled": true, + "path": "trace.trace_wikisort.speedscope.json" } } } diff --git a/scripts/analysis/quantify_bb_error.py b/scripts/analysis/quantify_error.py similarity index 97% rename from scripts/analysis/quantify_bb_error.py rename to scripts/analysis/quantify_error.py index 9476266..73b65ed 100644 --- a/scripts/analysis/quantify_bb_error.py +++ b/scripts/analysis/quantify_error.py @@ -87,6 +87,8 @@ def main(): if weighted_error == float("inf"): print("WeightedError: inf") else: + print(f"TotalError: {total_error:.6f}") + print(f"TotalTime: {total_time:.6f}") print(f"WeightedError: {weighted_error * 100:.4f}%") diff --git a/src/receivers/emulation/cyc_func_emulation_receiver.rs b/src/receivers/emulation/cyc_func_emulation_receiver.rs index 15e6c2f..44bde05 100644 --- a/src/receivers/emulation/cyc_func_emulation_receiver.rs +++ b/src/receivers/emulation/cyc_func_emulation_receiver.rs @@ -112,7 +112,7 @@ impl AbstractReceiver for CycFuncEmulationReceiver { let func_entry_time = self.func_entry_time_stack.pop().unwrap(); let delta_time = self.curr_cyc - func_entry_time; self.writer - .write_all(format!("{},{}", delta_time, frame.symbol.name).as_bytes()) + .write_all(format!("{},{},{},{}", delta_time, frame.symbol.name, func_entry_time, self.curr_cyc).as_bytes()) .unwrap(); self.writer.write_all(b"\n").unwrap(); } @@ -132,7 +132,7 @@ impl AbstractReceiver for CycFuncEmulationReceiver { let func_entry_time = self.func_entry_time_stack.pop().unwrap(); let delta_time = self.curr_cyc - func_entry_time; self.writer - .write_all(format!("{},{}", delta_time, frame.symbol.name).as_bytes()) + .write_all(format!("{},{},{},{}", delta_time, frame.symbol.name, func_entry_time, self.curr_cyc).as_bytes()) .unwrap(); self.writer.write_all(b"\n").unwrap(); } diff --git a/src/receivers/emulation/reference_func_receiver.rs b/src/receivers/emulation/reference_func_receiver.rs index c55beee..06c0db6 100644 --- a/src/receivers/emulation/reference_func_receiver.rs +++ b/src/receivers/emulation/reference_func_receiver.rs @@ -74,7 +74,7 @@ impl AbstractReceiver for ReferenceFuncReceiver { let func_entry_time = self.func_entry_time_stack.pop().unwrap(); let delta_time = timestamp - func_entry_time; self.writer - .write_all(format!("{},{}\n", delta_time, frame.symbol.name).as_bytes()) + .write_all(format!("{},{},{},{}\n", delta_time, frame.symbol.name, func_entry_time, timestamp).as_bytes()) .unwrap(); } From 2ee6c03c8149f5a39dffe079478e242163518774 Mon Sep 17 00:00:00 2001 From: Lux Date: Wed, 4 Mar 2026 19:01:37 -0800 Subject: [PATCH 21/24] fix: scan for all executable sections for machine mode binary as well --- src/common/insn_index.rs | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/common/insn_index.rs b/src/common/insn_index.rs index baba370..2d2a82c 100644 --- a/src/common/insn_index.rs +++ b/src/common/insn_index.rs @@ -52,13 +52,22 @@ pub fn build_instruction_index(cfg: DecoderStaticCfg) -> Result"), + addr, + m_insn_map.len() + ); + } + } + } if m_insn_map.is_empty() { return Err(anyhow::anyhow!( "No executable instructions found in SBI ELF" From 1169eab2b836b12a4d22aa070f1e07901ad73568 Mon Sep 17 00:00:00 2001 From: Lux Date: Mon, 16 Mar 2026 09:56:28 -0700 Subject: [PATCH 22/24] stash: minor changes to the emulation receivers --- .../emulation/cyc_func_emulation_receiver.rs | 47 ++++++++++++------- .../emulation/reference_func_receiver.rs | 15 ++++-- 2 files changed, 40 insertions(+), 22 deletions(-) diff --git a/src/receivers/emulation/cyc_func_emulation_receiver.rs b/src/receivers/emulation/cyc_func_emulation_receiver.rs index 44bde05..1bd01c5 100644 --- a/src/receivers/emulation/cyc_func_emulation_receiver.rs +++ b/src/receivers/emulation/cyc_func_emulation_receiver.rs @@ -15,7 +15,7 @@ pub struct CycFuncEmulationReceiver { n_tnt: u64, event_staging: Vec, unwinder: StackUnwinder, - func_entry_time_stack: Vec, + func_agg_time_stack: Vec, } /* Emulates the behavior of a CYC-based encoder, used for accuracy analysis @@ -38,7 +38,7 @@ impl CycFuncEmulationReceiver { n_tnt: 0, event_staging: Vec::new(), unwinder, - func_entry_time_stack: Vec::new(), + func_agg_time_stack: Vec::new(), } } } @@ -105,42 +105,55 @@ impl AbstractReceiver for CycFuncEmulationReceiver { let last_event = self.event_staging.pop().unwrap(); for event in self.event_staging.iter() { - self.curr_cyc += delta_cyc; + // first, always add the delta_cyc to the head value of func_agg_time_stack + if !self.func_agg_time_stack.is_empty() { + let head = self.func_agg_time_stack.pop().unwrap(); + self.func_agg_time_stack.push(head + delta_cyc); + } + if let Some(update) = self.unwinder.step(&Entry::Event { timestamp: self.curr_cyc, kind: event.clone() }) { for frame in update.frames_closed { - // pop the func_entry_time_stack - let func_entry_time = self.func_entry_time_stack.pop().unwrap(); - let delta_time = self.curr_cyc - func_entry_time; + // pop the func_agg_time_stack + let func_agg_time = self.func_agg_time_stack.pop().unwrap(); + let delta_time = func_agg_time; self.writer - .write_all(format!("{},{},{},{}", delta_time, frame.symbol.name, func_entry_time, self.curr_cyc).as_bytes()) + .write_all(format!("{},{},{},{}", delta_time, frame.symbol.name, func_agg_time, self.curr_cyc).as_bytes()) .unwrap(); self.writer.write_all(b"\n").unwrap(); } if let Some(_) = update.frames_opened { - // push the current cycle to the func_entry_time_stack - self.func_entry_time_stack.push(self.curr_cyc); + // push the current cycle to the func_agg_time_stack + self.func_agg_time_stack.push(0); } } + self.curr_cyc += delta_cyc; } // handle the last event - self.curr_cyc += delta_cyc + slack % num_events; - assert_eq!(self.curr_cyc, timestamp); + // first, always add the delta_cyc to the head value of func_agg_time_stack + if !self.func_agg_time_stack.is_empty() { + let head = self.func_agg_time_stack.pop().unwrap(); + let new_head = head + delta_cyc + slack % num_events; + self.func_agg_time_stack.push(new_head); + } + if let Some(update) = self.unwinder.step(&Entry::Event { timestamp: timestamp, kind: last_event.clone() }) { for frame in update.frames_closed { - // pop the func_entry_time_stack - let func_entry_time = self.func_entry_time_stack.pop().unwrap(); - let delta_time = self.curr_cyc - func_entry_time; + // pop the func_agg_time_stack + let func_agg_time = self.func_agg_time_stack.pop().unwrap(); + let delta_time = func_agg_time; self.writer - .write_all(format!("{},{},{},{}", delta_time, frame.symbol.name, func_entry_time, self.curr_cyc).as_bytes()) + .write_all(format!("{},{},{},{}", delta_time, frame.symbol.name, func_agg_time, self.curr_cyc).as_bytes()) .unwrap(); self.writer.write_all(b"\n").unwrap(); } if let Some(_) = update.frames_opened { - // push the current cycle to the func_entry_time_stack - self.func_entry_time_stack.push(self.curr_cyc); + // push the current cycle to the func_agg_time_stack + self.func_agg_time_stack.push(0); } } + self.curr_cyc += delta_cyc + slack % num_events; + assert_eq!(self.curr_cyc, timestamp); // clear the states self.event_staging.clear(); self.n_tnt = 0; diff --git a/src/receivers/emulation/reference_func_receiver.rs b/src/receivers/emulation/reference_func_receiver.rs index 06c0db6..98e0923 100644 --- a/src/receivers/emulation/reference_func_receiver.rs +++ b/src/receivers/emulation/reference_func_receiver.rs @@ -68,20 +68,25 @@ impl AbstractReceiver for ReferenceFuncReceiver { self.curr_timestamp = timestamp; } Entry::Event { timestamp, kind } => { - self.curr_timestamp = timestamp; + // first, always add the timestamp to the head value of func_entry_time_stack + if !self.func_entry_time_stack.is_empty() { + let head = self.func_entry_time_stack.pop().unwrap(); + self.func_entry_time_stack.push(head + timestamp - self.curr_timestamp); + } + if let Some(update) = self.unwinder.step(&Entry::Event { timestamp, kind }) { for frame in update.frames_closed { - let func_entry_time = self.func_entry_time_stack.pop().unwrap(); - let delta_time = timestamp - func_entry_time; + let delta_time = self.func_entry_time_stack.pop().unwrap(); self.writer - .write_all(format!("{},{},{},{}\n", delta_time, frame.symbol.name, func_entry_time, timestamp).as_bytes()) + .write_all(format!("{},{}\n", delta_time, frame.symbol.name).as_bytes()) .unwrap(); } if let Some(_) = update.frames_opened { - self.func_entry_time_stack.push(timestamp); + self.func_entry_time_stack.push(0); // 0 means the function has not started yet } } + self.curr_timestamp = timestamp; } _ => {} } From decdc1d3c65cb33250f379ce1f6dd639cfae23db Mon Sep 17 00:00:00 2001 From: Lux Date: Mon, 16 Mar 2026 10:19:20 -0700 Subject: [PATCH 23/24] fix: tweak the configs a bit --- .../baremetal_hello/baremetal_hello_boom.json | 16 ++-------------- configs/embench/baremetal_huffbench.json | 2 +- configs/linux/linux_firesim.json | 7 ++++--- 3 files changed, 7 insertions(+), 18 deletions(-) diff --git a/configs/baremetal_hello/baremetal_hello_boom.json b/configs/baremetal_hello/baremetal_hello_boom.json index 161fdd3..2642e1f 100644 --- a/configs/baremetal_hello/baremetal_hello_boom.json +++ b/configs/baremetal_hello/baremetal_hello_boom.json @@ -6,19 +6,7 @@ "kernel_jump_label_patch_log": "", "driver_binary_entry_tuples": [], "receivers": { - "txt_delta": { - "enabled": true, - "path": "trace.trace_hello.txt_delta.txt" - }, - "tc_bb_emulation": { - "enabled": true, - "path": "trace.trace_hello.tc_bb_emulation.txt", - "interval": 1000 - }, - "cyc_bb_emulation": { - "enabled": true, - "path": "trace.trace_hello.cyc_bb_emulation.txt", - "lim_tnt": 47 - } + "txt": { "enabled": true, "path": "trace.trace_hello.txt" }, + "speedscope": { "enabled": true, "path": "trace.trace_hello.speedscope.json" } } } \ No newline at end of file diff --git a/configs/embench/baremetal_huffbench.json b/configs/embench/baremetal_huffbench.json index 1c280ae..2708627 100644 --- a/configs/embench/baremetal_huffbench.json +++ b/configs/embench/baremetal_huffbench.json @@ -30,7 +30,7 @@ "lim_tnt": 47 }, "speedscope": { - "enabled": true, + "enabled": false, "path": "trace.trace_huffbench.speedscope.json" } } diff --git a/configs/linux/linux_firesim.json b/configs/linux/linux_firesim.json index 34dd321..48062e6 100644 --- a/configs/linux/linux_firesim.json +++ b/configs/linux/linux_firesim.json @@ -6,12 +6,13 @@ ], "machine_binary": "../firemarshal/images/firechip/trace-hello/trace-hello-bin", "kernel_binary": "../firemarshal/images/firechip/trace-hello/trace-hello-bin-dwarf", - "kernel_jump_label_patch_log": "/scratch/iansseijelly/tacit-chipyard/sims/firesim/deploy/results-workload/2026-01-06--05-35-54-trace-hello/trace-hello-run-chores/jump_label_patch_map.txt", + "kernel_jump_label_patch_log": "/scratch/iansseijelly/tacit-chipyard/sims/firesim/deploy/results-workload/2026-03-12--19-05-49-trace-hello/trace-hello-run-chores/jump_label_patch_map.txt", "driver_binary_entry_tuples": [ - ["../firemarshal/images/firechip/trace-hello/tacit-dwarf", "0xffffffff0169d000"], - ["../firemarshal/images/firechip/trace-hello/iceblk-dwarf", "0xffffffff016ac000"] + ["../firemarshal/images/firechip/trace-hello/tacit-dwarf", "0xffffffff01b08000"], + ["../firemarshal/images/firechip/trace-hello/iceblk-dwarf", "0xffffffff01aa7000"] ], "receivers": { + "txt": { "enabled": true, "path": "trace.txt" }, "speedscope": { "enabled": true, "path": "trace.speedscope.json" } } } From 0ab85ffedfe0b1092223597861a6381a904310ce Mon Sep 17 00:00:00 2001 From: Lux Date: Fri, 3 Apr 2026 20:45:58 -0700 Subject: [PATCH 24/24] add: staging everything --- .gitignore | 3 +- Cargo.lock | 1090 +++++++++++------ Cargo.toml | 3 + .../baremetal_boom_stress.json | 12 + configs/embench/baremetal_wikisort.json | 49 +- configs/linux/linux_ipi_storm_0.json | 60 + configs/linux/linux_ipi_storm_1.json | 62 + configs/linux/linux_process_launch.json | 116 +- .../spec-emulation/linux_600_perlbench.json | 97 ++ configs/spec-emulation/linux_602_gcc.json | 54 + configs/spec-emulation/linux_605_mcf.json | 54 + configs/spec-emulation/linux_620_omnetpp.json | 54 + .../spec-emulation/linux_623_xalancbmk.json | 54 + configs/spec-emulation/linux_625_x264.json | 54 + .../spec-emulation/linux_631_deepsjeng.json | 45 + configs/spec-emulation/linux_641_leela.json | 54 + .../spec-emulation/linux_648_exchange2.json | 54 + configs/spec-emulation/linux_657_xz_cld.json | 54 + .../linux_657_xz_cpu2006docs.json | 54 + configs/spec/linux_600_perlbench.json | 82 +- configs/spec/linux_602_gcc.json | 45 + configs/spec/linux_605_mcf.json | 26 +- configs/spec/linux_620_omnetpp.json | 33 + configs/spec/linux_623_xalancbmk.json | 33 + configs/spec/linux_625_x264.json | 33 +- configs/spec/linux_641_leela.json | 33 +- configs/spec/linux_648_exchange2.json | 33 +- configs/spec/linux_657_xz_cld.json | 33 + configs/spec/linux_657_xz_cpu2006docs.json | 33 + crates/trace_db_tools/Cargo.toml | 10 + crates/trace_db_tools/src/bb_stats.rs | 185 +++ crates/trace_db_tools/src/check.rs | 121 ++ crates/trace_db_tools/src/main.rs | 54 + scripts/analysis/plot_bb_stats.py | 231 ++++ scripts/analysis/plot_emulation_errors.py | 196 +++ scripts/analysis/plot_func_path_pareto.py | 128 ++ scripts/analysis/plot_iteration_breakdown.py | 232 ++++ scripts/analysis/plot_post_exit.py | 57 + scripts/analysis/plot_vbb.sh | 37 + scripts/analysis/quantify_error.py | 92 +- scripts/analysis/quantify_error_twofiles.py | 96 ++ scripts/config/populate_asids_from_log.py | 50 + scripts/run_spec_decode_all.sh | 22 + scripts/sql/bb_stats.py | 98 ++ src/backend/event.rs | 4 +- src/main.rs | 3 +- src/receivers/analysis/func_path_receiver.rs | 397 ++++++ .../analysis/iteration_breakdown_receiver.rs | 282 +++++ src/receivers/emulation/abstract_emulator.rs | 18 + src/receivers/emulation/bb_analyzer.rs | 65 + .../emulation/cyc_func_emulation_receiver.rs | 2 +- .../emulation/emulation_receivers.rs | 109 ++ src/receivers/emulation/func_analyzer.rs | 102 ++ src/receivers/emulation/mod.rs | 21 + .../emulation/reference_func_receiver.rs | 2 +- src/receivers/emulation/tc_emulator.rs | 79 ++ .../emulation/tnt_cyc_nret_emulator.rs | 98 ++ .../tnt_cyc_retcompressed_emulator.rs | 146 +++ src/receivers/mod.rs | 40 +- .../speedscope_receiver.rs | 0 src/receivers/print/sqlite_receiver.rs | 193 +++ .../{analysis => print}/stack_txt_receiver.rs | 0 .../{analysis => print}/txt_delta_receiver.rs | 0 .../{analysis => print}/txt_receiver.rs | 0 64 files changed, 5000 insertions(+), 577 deletions(-) create mode 100644 configs/baremetal_hello/baremetal_boom_stress.json create mode 100644 configs/linux/linux_ipi_storm_0.json create mode 100644 configs/linux/linux_ipi_storm_1.json create mode 100644 configs/spec-emulation/linux_600_perlbench.json create mode 100644 configs/spec-emulation/linux_602_gcc.json create mode 100644 configs/spec-emulation/linux_605_mcf.json create mode 100644 configs/spec-emulation/linux_620_omnetpp.json create mode 100644 configs/spec-emulation/linux_623_xalancbmk.json create mode 100644 configs/spec-emulation/linux_625_x264.json create mode 100644 configs/spec-emulation/linux_631_deepsjeng.json create mode 100644 configs/spec-emulation/linux_641_leela.json create mode 100644 configs/spec-emulation/linux_648_exchange2.json create mode 100644 configs/spec-emulation/linux_657_xz_cld.json create mode 100644 configs/spec-emulation/linux_657_xz_cpu2006docs.json create mode 100644 configs/spec/linux_602_gcc.json create mode 100644 configs/spec/linux_620_omnetpp.json create mode 100644 configs/spec/linux_623_xalancbmk.json create mode 100644 configs/spec/linux_657_xz_cld.json create mode 100644 configs/spec/linux_657_xz_cpu2006docs.json create mode 100644 crates/trace_db_tools/Cargo.toml create mode 100644 crates/trace_db_tools/src/bb_stats.rs create mode 100644 crates/trace_db_tools/src/check.rs create mode 100644 crates/trace_db_tools/src/main.rs create mode 100644 scripts/analysis/plot_bb_stats.py create mode 100644 scripts/analysis/plot_emulation_errors.py create mode 100644 scripts/analysis/plot_func_path_pareto.py create mode 100644 scripts/analysis/plot_iteration_breakdown.py create mode 100644 scripts/analysis/plot_post_exit.py create mode 100755 scripts/analysis/plot_vbb.sh create mode 100644 scripts/analysis/quantify_error_twofiles.py create mode 100755 scripts/config/populate_asids_from_log.py create mode 100755 scripts/run_spec_decode_all.sh create mode 100644 scripts/sql/bb_stats.py create mode 100644 src/receivers/analysis/func_path_receiver.rs create mode 100644 src/receivers/analysis/iteration_breakdown_receiver.rs create mode 100644 src/receivers/emulation/abstract_emulator.rs create mode 100644 src/receivers/emulation/bb_analyzer.rs create mode 100644 src/receivers/emulation/emulation_receivers.rs create mode 100644 src/receivers/emulation/func_analyzer.rs create mode 100644 src/receivers/emulation/mod.rs create mode 100644 src/receivers/emulation/tc_emulator.rs create mode 100644 src/receivers/emulation/tnt_cyc_nret_emulator.rs create mode 100644 src/receivers/emulation/tnt_cyc_retcompressed_emulator.rs rename src/receivers/{analysis => print}/speedscope_receiver.rs (100%) create mode 100644 src/receivers/print/sqlite_receiver.rs rename src/receivers/{analysis => print}/stack_txt_receiver.rs (100%) rename src/receivers/{analysis => print}/txt_delta_receiver.rs (100%) rename src/receivers/{analysis => print}/txt_receiver.rs (100%) diff --git a/.gitignore b/.gitignore index 9a1d493..a3dd648 100644 --- a/.gitignore +++ b/.gitignore @@ -15,4 +15,5 @@ target-rust-analyzer/ *.log *.speedscope.json *.csv - +*.png +*.sqlite.db* diff --git a/Cargo.lock b/Cargo.lock index 97997c0..fb043ce 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,7 +11,7 @@ dependencies = [ "cpp_demangle", "fallible-iterator", "gimli", - "memmap2 0.9.5", + "memmap2 0.9.10", "object", "rustc-demangle", "smallvec", @@ -20,18 +20,18 @@ dependencies = [ [[package]] name = "adler2" -version = "2.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "ahash" -version = "0.8.11" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ - "cfg-if 1.0.0", - "getrandom 0.2.15", + "cfg-if 1.0.4", + "getrandom 0.3.4", "once_cell", "serde", "version_check", @@ -40,18 +40,18 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" dependencies = [ "memchr", ] [[package]] name = "anstream" -version = "0.6.18" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" +checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d" dependencies = [ "anstyle", "anstyle-parse", @@ -64,44 +64,44 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.10" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" +checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" [[package]] name = "anstyle-parse" -version = "0.2.6" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" +checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.2" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" +checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] name = "anstyle-wincon" -version = "3.0.7" +version = "3.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" +checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" dependencies = [ "anstyle", - "once_cell", - "windows-sys 0.59.0", + "once_cell_polyfill", + "windows-sys 0.61.2", ] [[package]] name = "anyhow" -version = "1.0.96" +version = "1.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b964d184e89d9b6b67dd2715bc8e74cf3107fb2b529990c90cf517326150bf4" +checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" [[package]] name = "arrayvec" @@ -111,24 +111,9 @@ checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "autocfg" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" - -[[package]] -name = "backtrace" -version = "0.3.74" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" -dependencies = [ - "addr2line", - "cfg-if 1.0.0", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", - "windows-targets 0.52.6", -] +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "base64" @@ -159,15 +144,15 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.8.0" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36" +checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" [[package]] name = "bumpalo" -version = "3.17.0" +version = "3.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" +checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" [[package]] name = "bus" @@ -182,15 +167,25 @@ dependencies = [ [[package]] name = "bytecount" -version = "0.6.8" +version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ce89b21cab1437276d2650d57e971f9d548a2d9037cc231abdc0562b97498ce" +checksum = "175812e0be2bccb6abe50bb8d566126198344f707e304f45c648fd8f2cc0365e" [[package]] name = "bytes" -version = "1.10.0" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" + +[[package]] +name = "cc" +version = "1.2.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f61dac84819c6588b558454b194026eb1f09c293b9036ae9b159e74e73ab6cf9" +checksum = "e1e928d4b69e3077709075a938a05ffbedfa53a84c8f766efbf8220bb1ff60e1" +dependencies = [ + "find-msvc-tools", + "shlex", +] [[package]] name = "cfg-if" @@ -200,15 +195,21 @@ checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" [[package]] name = "cfg-if" -version = "1.0.0" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "circular-buffer" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c638459986b83c2b885179bd4ea6a2cbb05697b001501a56adb3a3d230803b" [[package]] name = "clap" -version = "4.5.36" +version = "4.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2df961d8c8a0d08aa9945718ccf584145eee3f3aa06cddbeac12933781102e04" +checksum = "b193af5b67834b676abd72466a96c1024e6a6ad978a1f484bd90b85c94041351" dependencies = [ "clap_builder", "clap_derive", @@ -216,9 +217,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.36" +version = "4.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "132dbda40fb6753878316a489d5a1242a8ef2f0d9e47ba01c951ea8aa7d013a5" +checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f" dependencies = [ "anstream", "anstyle", @@ -228,9 +229,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.32" +version = "4.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7" +checksum = "1110bd8a634a1ab8cb04345d8d878267d57c3cf1b38d91b71af6686408bbca6a" dependencies = [ "heck", "proc-macro2", @@ -240,25 +241,24 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.4" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" +checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" [[package]] name = "colorchoice" -version = "1.0.3" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" +checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" [[package]] name = "console" -version = "0.16.1" +version = "0.16.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b430743a6eb14e9764d4260d4c0d8123087d504eeb9c48f2b2a5e810dd369df4" +checksum = "d64e8af5551369d19cf50138de61f1c42074ab970f74e99be916646777f8fc87" dependencies = [ "encode_unicode", "libc", - "once_cell", "unicode-width", "windows-sys 0.61.2", ] @@ -281,27 +281,27 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cpp_demangle" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96e58d342ad113c2b878f16d5d034c03be492ae460cdbc02b7f0f2284d310c7d" +checksum = "f2bb79cb74d735044c972aae58ed0aaa9a837e85b01106a54c39e42e97f62253" dependencies = [ - "cfg-if 1.0.0", + "cfg-if 1.0.4", ] [[package]] name = "crc32fast" -version = "1.4.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" dependencies = [ - "cfg-if 1.0.0", + "cfg-if 1.0.4", ] [[package]] name = "crossbeam-channel" -version = "0.5.14" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ba6d68e24814cb8de6bb986db8222d3a027d15872cabc0d18817bc3c0e4471" +checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" dependencies = [ "crossbeam-utils", ] @@ -333,9 +333,9 @@ checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "deranged" -version = "0.3.11" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" dependencies = [ "powerfmt", ] @@ -359,9 +359,9 @@ checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] name = "ena" -version = "0.14.3" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d248bdd43ce613d87415282f69b9bb99d947d290b10962dd6c56233312c2ad5" +checksum = "eabffdaee24bd1bf95c5ef7cec31260444317e72ea56c4c91750e8b7ee58d5f1" dependencies = [ "log", ] @@ -378,14 +378,14 @@ version = "0.8.35" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" dependencies = [ - "cfg-if 1.0.0", + "cfg-if 1.0.4", ] [[package]] name = "env_filter" -version = "0.1.3" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0" +checksum = "32e90c2accc4b07a8456ea0debdc2e7587bdd890680d71173a15d4ae604f6eef" dependencies = [ "log", "regex", @@ -406,14 +406,14 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.11.6" +version = "0.11.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcaee3d8e3cfc3fd92428d477bc97fc29ec8716d180c0d74c643bb26166660e0" +checksum = "0621c04f2196ac3f488dd583365b9c09be011a4ab8b9f37248ffcc8f6198b56a" dependencies = [ "anstream", "anstyle", "env_filter", - "humantime", + "jiff", "log", ] @@ -439,6 +439,12 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" +[[package]] +name = "fallible-streaming-iterator" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" + [[package]] name = "fancy-regex" version = "0.11.0" @@ -455,11 +461,17 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +[[package]] +name = "find-msvc-tools" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" + [[package]] name = "flate2" -version = "1.1.0" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11faaf5a5236997af9848be0bef4db95824b1d534ebc64d0f0c6cf3e67bd38dc" +checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" dependencies = [ "crc32fast", "miniz_oxide", @@ -471,11 +483,17 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + [[package]] name = "form_urlencoded" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" dependencies = [ "percent-encoding", ] @@ -492,49 +510,48 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" dependencies = [ "futures-core", ] [[package]] name = "futures-core" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" +checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" [[package]] name = "futures-io" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" +checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" [[package]] name = "futures-sink" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" +checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" [[package]] name = "futures-task" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" +checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" [[package]] name = "futures-util" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" dependencies = [ "futures-core", "futures-io", "futures-task", "memchr", "pin-project-lite", - "pin-utils", "slab", ] @@ -544,19 +561,19 @@ version = "0.1.0" dependencies = [ "addr2line", "anyhow", - "env_logger 0.11.6", - "indexmap 2.7.1", + "env_logger 0.11.10", + "indexmap 2.13.0", "log", "object", ] [[package]] name = "getrandom" -version = "0.2.15" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" dependencies = [ - "cfg-if 1.0.0", + "cfg-if 1.0.4", "js-sys", "libc", "wasi", @@ -569,10 +586,23 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ - "cfg-if 1.0.0", + "cfg-if 1.0.4", + "libc", + "r-efi 5.3.0", + "wasip2", +] + +[[package]] +name = "getrandom" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" +dependencies = [ + "cfg-if 1.0.4", "libc", - "r-efi", + "r-efi 6.0.0", "wasip2", + "wasip3", ] [[package]] @@ -587,9 +617,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.26" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" +checksum = "0beca50380b1fc32983fc1cb4587bfa4bb9e78fc259aad4a0032d2080309222d" dependencies = [ "bytes", "fnv", @@ -597,7 +627,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 2.7.1", + "indexmap 2.13.0", "slab", "tokio", "tokio-util", @@ -612,27 +642,48 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" -version = "0.15.2" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", +] [[package]] -name = "heck" -version = "0.5.0" +name = "hashbrown" +version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "foldhash", +] [[package]] -name = "hermit-abi" -version = "0.3.9" +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" + +[[package]] +name = "hashlink" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af" +dependencies = [ + "hashbrown 0.14.5", +] + +[[package]] +name = "heck" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" -version = "0.4.0" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" [[package]] name = "http" @@ -658,9 +709,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.10.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2d708df4e7140240a16cd6ab0ab65c972d7433ab77819ea693fde9c43811e2a" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" [[package]] name = "httpdate" @@ -670,9 +721,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "humantime" -version = "2.1.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" +checksum = "135b12329e5e3ce057a9f972339ea52bc954fe1e9358ef27f95e89716fbc5424" [[package]] name = "hyper" @@ -691,7 +742,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2", + "socket2 0.5.10", "tokio", "tower-service", "tracing", @@ -700,21 +751,23 @@ dependencies = [ [[package]] name = "icu_collections" -version = "1.5.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c" dependencies = [ "displaydoc", + "potential_utf", + "utf8_iter", "yoke", "zerofrom", "zerovec", ] [[package]] -name = "icu_locid" -version = "1.5.0" +name = "icu_locale_core" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29" dependencies = [ "displaydoc", "litemap", @@ -723,104 +776,72 @@ dependencies = [ "zerovec", ] -[[package]] -name = "icu_locid_transform" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" -dependencies = [ - "displaydoc", - "icu_locid", - "icu_locid_transform_data", - "icu_provider", - "tinystr", - "zerovec", -] - -[[package]] -name = "icu_locid_transform_data" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" - [[package]] name = "icu_normalizer" -version = "1.5.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4" dependencies = [ - "displaydoc", "icu_collections", "icu_normalizer_data", "icu_properties", "icu_provider", "smallvec", - "utf16_iter", - "utf8_iter", - "write16", "zerovec", ] [[package]] name = "icu_normalizer_data" -version = "1.5.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" +checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38" [[package]] name = "icu_properties" -version = "1.5.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de" dependencies = [ - "displaydoc", "icu_collections", - "icu_locid_transform", + "icu_locale_core", "icu_properties_data", "icu_provider", - "tinystr", + "zerotrie", "zerovec", ] [[package]] name = "icu_properties_data" -version = "1.5.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" +checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14" [[package]] name = "icu_provider" -version = "1.5.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421" dependencies = [ "displaydoc", - "icu_locid", - "icu_provider_macros", - "stable_deref_trait", - "tinystr", + "icu_locale_core", "writeable", "yoke", "zerofrom", + "zerotrie", "zerovec", ] [[package]] -name = "icu_provider_macros" -version = "1.5.0" +name = "id-arena" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] +checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" [[package]] name = "idna" -version = "1.0.3" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" dependencies = [ "idna_adapter", "smallvec", @@ -829,9 +850,9 @@ dependencies = [ [[package]] name = "idna_adapter" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" dependencies = [ "icu_normalizer", "icu_properties", @@ -850,19 +871,21 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.7.1" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652" +checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" dependencies = [ "equivalent", - "hashbrown 0.15.2", + "hashbrown 0.16.1", + "serde", + "serde_core", ] [[package]] name = "indicatif" -version = "0.18.0" +version = "0.18.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70a646d946d06bedbbc4cac4c218acf4bbf2d87757a784857025f4d447e4e1cd" +checksum = "25470f23803092da7d239834776d653104d551bc4d7eacaf31e6837854b8e9eb" dependencies = [ "console", "portable-atomic", @@ -873,50 +896,74 @@ dependencies = [ [[package]] name = "inventory" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc61209c082fbeb19919bee74b176221b27223e27b65d781eb91af24eb1fb46e" +checksum = "a4f0c30c76f2f4ccee3fe55a2435f691ca00c0e4bd87abe4f4a851b1d4dac39b" dependencies = [ "rustversion", ] [[package]] name = "ipnet" -version = "2.11.0" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" +checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" [[package]] name = "is-terminal" -version = "0.4.15" +version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e19b23d53f35ce9f56aebc7d1bb4e6ac1e9c0db7ac85c8d1760c04379edced37" +checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46" dependencies = [ - "hermit-abi 0.4.0", + "hermit-abi", "libc", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] name = "is_terminal_polyfill" -version = "1.70.1" +version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" [[package]] name = "iso8601" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5c177cff824ab21a6f41079a4c401241c4e8be14f316c4c6b07d5fca351c98d" +checksum = "e1082f0c48f143442a1ac6122f67e360ceee130b967af4d50996e5154a45df46" dependencies = [ "nom", ] [[package]] name = "itoa" -version = "1.0.14" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "jiff" +version = "0.2.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a3546dc96b6d42c5f24902af9e2538e82e39ad350b0c766eb3fbf2d8f3d8359" +dependencies = [ + "jiff-static", + "log", + "portable-atomic", + "portable-atomic-util", + "serde_core", +] + +[[package]] +name = "jiff-static" +version = "0.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" +checksum = "2a8c8b344124222efd714b73bb41f8b5120b27a7cc1c75593a6ff768d9d05aa4" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] name = "jobserver" @@ -930,10 +977,12 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.77" +version = "0.3.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +checksum = "2e04e2ef80ce82e13552136fabeef8a5ed1f985a96805761cbb9a2c34e7664d9" dependencies = [ + "cfg-if 1.0.4", + "futures-util", "once_cell", "wasm-bindgen", ] @@ -951,7 +1000,7 @@ dependencies = [ "clap", "fancy-regex", "fraction", - "getrandom 0.2.15", + "getrandom 0.2.17", "iso8601", "itoa", "memchr", @@ -974,45 +1023,61 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +[[package]] +name = "leb128fmt" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" + [[package]] name = "libc" -version = "0.2.177" +version = "0.2.184" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" +checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af" + +[[package]] +name = "libsqlite3-sys" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c10584274047cb335c23d3e61bcef8e323adae7c5c8c760540f73610177fc3f" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] [[package]] name = "linux-raw-sys" -version = "0.11.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" [[package]] name = "litemap" -version = "0.7.5" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856" +checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" [[package]] name = "lock_api" -version = "0.4.12" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" dependencies = [ - "autocfg", "scopeguard", ] [[package]] name = "log" -version = "0.4.26" +version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" [[package]] name = "memchr" -version = "2.7.4" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" [[package]] name = "memmap2" @@ -1025,9 +1090,9 @@ dependencies = [ [[package]] name = "memmap2" -version = "0.9.5" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd3f7eed9d3848f8b98834af67102b720745c4ec028fcd0aa0239277e7de374f" +checksum = "714098028fe011992e1c3962653c96b2d578c4b4bce9036e15ff220319b1e0e3" dependencies = [ "libc", ] @@ -1040,22 +1105,23 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "miniz_oxide" -version = "0.8.5" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ "adler2", + "simd-adler32", ] [[package]] name = "mio" -version = "1.0.3" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" +checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" dependencies = [ "libc", "wasi", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -1108,9 +1174,9 @@ dependencies = [ [[package]] name = "num-conv" -version = "0.1.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" +checksum = "c6673768db2d862beb9b39a78fdcb1a69439615d5794a1be50caa9bc92c81967" [[package]] name = "num-integer" @@ -1154,11 +1220,11 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" dependencies = [ - "hermit-abi 0.3.9", + "hermit-abi", "libc", ] @@ -1175,15 +1241,21 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.20.3" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" + +[[package]] +name = "once_cell_polyfill" +version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e" +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" [[package]] name = "parking_lot" -version = "0.12.3" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" dependencies = [ "lock_api", "parking_lot_core", @@ -1191,40 +1263,58 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.10" +version = "0.9.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ - "cfg-if 1.0.0", + "cfg-if 1.0.4", "libc", "redox_syscall", "smallvec", - "windows-targets 0.52.6", + "windows-link", ] [[package]] name = "percent-encoding" -version = "2.3.1" +version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "pin-project-lite" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" [[package]] -name = "pin-utils" -version = "0.1.0" +name = "pkg-config" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] name = "portable-atomic" -version = "1.11.1" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" + +[[package]] +name = "portable-atomic-util" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" +checksum = "091397be61a01d4be58e7841595bd4bfedb15f1cd54977d79b8271e94ed799a3" +dependencies = [ + "portable-atomic", +] + +[[package]] +name = "potential_utf" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564" +dependencies = [ + "zerovec", +] [[package]] name = "powerfmt" @@ -1232,20 +1322,30 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" +[[package]] +name = "prettyplease" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +dependencies = [ + "proc-macro2", + "syn", +] + [[package]] name = "proc-macro2" -version = "1.0.93" +version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.38" +version = "1.0.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" dependencies = [ "proc-macro2", ] @@ -1256,20 +1356,26 @@ version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + [[package]] name = "redox_syscall" -version = "0.5.9" +version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82b568323e98e49e2a0899dcee453dd679fae22d69adf9b11dd508d1549b7e2f" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.8.0", + "bitflags 2.11.0", ] [[package]] name = "regex" -version = "1.11.1" +version = "1.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" dependencies = [ "aho-corasick", "memchr", @@ -1279,9 +1385,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.9" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" dependencies = [ "aho-corasick", "memchr", @@ -1290,9 +1396,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.5" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" [[package]] name = "reqwest" @@ -1330,11 +1436,25 @@ dependencies = [ "winreg", ] +[[package]] +name = "rusqlite" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b838eba278d213a8beaf485bd313fd580ca4505a00d5871caeb1457c55322cae" +dependencies = [ + "bitflags 2.11.0", + "fallible-iterator", + "fallible-streaming-iterator", + "hashlink", + "libsqlite3-sys", + "smallvec", +] + [[package]] name = "rustc-demangle" -version = "0.1.24" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +checksum = "b50b8869d9fc858ce7266cce0194bd74df58b9d0e3f6df3a9fc8eb470d95c09d" [[package]] name = "rustc-hash" @@ -1411,11 +1531,11 @@ dependencies = [ [[package]] name = "rustix" -version = "1.1.2" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" +checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ - "bitflags 2.8.0", + "bitflags 2.11.0", "errno", "libc", "linux-raw-sys", @@ -1424,9 +1544,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.19" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "ruzstd" @@ -1449,9 +1569,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.19" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd" +checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" [[package]] name = "scopeguard" @@ -1459,20 +1579,36 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "semver" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" + [[package]] name = "serde" -version = "1.0.218" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8dfc9d19bdbf6d17e22319da49161d5d0108e4188e8b680aef6299eed22df60" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.218" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f09503e191f4e797cb8aac08e9a4a4695c5edf6a2e70e376d961ddd5c969f82b" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", @@ -1481,14 +1617,15 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.139" +version = "1.0.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44f86c3acccc9c65b153fe1b85a3be07fe5515274ec9f0653b4a0875731c72a6" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" dependencies = [ "itoa", "memchr", - "ryu", "serde", + "serde_core", + "zmij", ] [[package]] @@ -1503,36 +1640,55 @@ dependencies = [ "serde", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "simd-adler32" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" + [[package]] name = "slab" -version = "0.4.9" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg", -] +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" [[package]] name = "smallvec" -version = "1.14.0" +version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "socket2" -version = "0.5.8" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" +checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" dependencies = [ "libc", "windows-sys 0.52.0", ] +[[package]] +name = "socket2" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + [[package]] name = "stable_deref_trait" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" [[package]] name = "static_assertions" @@ -1548,9 +1704,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.98" +version = "2.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" dependencies = [ "proc-macro2", "quote", @@ -1565,9 +1721,9 @@ checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" [[package]] name = "synstructure" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", @@ -1602,15 +1758,17 @@ dependencies = [ "addr2line", "anyhow", "bus", + "circular-buffer", "clap", "env_logger 0.10.2", "gcno_reader", - "indexmap 2.7.1", + "indexmap 2.13.0", "indicatif", "inventory", "jsonschema", "log", "object", + "rusqlite", "rustc_data_structures", "rvdasm", "serde", @@ -1619,12 +1777,12 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.23.0" +version = "3.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" +checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", - "getrandom 0.3.4", + "getrandom 0.4.2", "once_cell", "rustix", "windows-sys 0.61.2", @@ -1641,29 +1799,29 @@ dependencies = [ [[package]] name = "time" -version = "0.3.37" +version = "0.3.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21" +checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" dependencies = [ "deranged", "num-conv", "powerfmt", - "serde", + "serde_core", "time-core", "time-macros", ] [[package]] name = "time-core" -version = "0.1.2" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" +checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" [[package]] name = "time-macros" -version = "0.2.19" +version = "0.2.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2834e6017e3e5e4b9834939793b282bc03b37a3336245fa820e35e233e2a85de" +checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" dependencies = [ "num-conv", "time-core", @@ -1671,9 +1829,9 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.7.6" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d" dependencies = [ "displaydoc", "zerovec", @@ -1681,24 +1839,23 @@ dependencies = [ [[package]] name = "tokio" -version = "1.43.0" +version = "1.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d61fa4ffa3de412bfea335c6ecff681de2b609ba3c77ef3e00e521813a9ed9e" +checksum = "27ad5e34374e03cfffefc301becb44e9dc3c17584f414349ebe29ed26661822d" dependencies = [ - "backtrace", "bytes", "libc", "mio", "pin-project-lite", - "socket2", - "windows-sys 0.52.0", + "socket2 0.6.3", + "windows-sys 0.61.2", ] [[package]] name = "tokio-util" -version = "0.7.13" +version = "0.7.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7fcaa8d55a2bdd6b83ace262b016eca0d79ee02818c5c1bcdf0305114081078" +checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" dependencies = [ "bytes", "futures-core", @@ -1713,11 +1870,21 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" +[[package]] +name = "trace_db_tools" +version = "0.1.0" +dependencies = [ + "anyhow", + "clap", + "indicatif", + "rusqlite", +] + [[package]] name = "tracing" -version = "0.1.41" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" dependencies = [ "pin-project-lite", "tracing-attributes", @@ -1726,9 +1893,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.30" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", @@ -1737,9 +1904,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.33" +version = "0.1.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" dependencies = [ "once_cell", ] @@ -1756,7 +1923,7 @@ version = "1.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" dependencies = [ - "cfg-if 1.0.0", + "cfg-if 1.0.4", "static_assertions", ] @@ -1768,9 +1935,9 @@ checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a" [[package]] name = "unicode-ident" -version = "1.0.17" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00e2473a93778eb0bad35909dff6a10d28e63f792f16ed15e404fca9d5eeedbe" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" [[package]] name = "unicode-width" @@ -1778,29 +1945,30 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + [[package]] name = "unit-prefix" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "323402cff2dd658f39ca17c789b502021b3f18707c91cdf22e3838e1b4023817" +checksum = "81e544489bf3d8ef66c953931f56617f423cd4b5494be343d9b9d3dda037b9a3" [[package]] name = "url" -version = "2.5.4" +version = "2.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" dependencies = [ "form_urlencoded", "idna", "percent-encoding", + "serde", ] -[[package]] -name = "utf16_iter" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" - [[package]] name = "utf8_iter" version = "1.0.4" @@ -1815,9 +1983,19 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.15.1" +version = "1.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ac8b6f42ead25368cf5b098aeb3dc8a1a2c05a3eee8a9a1a68c640edbfc79d9" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "vcpkg" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0f540e3240398cce6128b64ba83fdbdd86129c16a3aa1a3a252efd66eb3d587" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "version_check" @@ -1836,63 +2014,56 @@ dependencies = [ [[package]] name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" +version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasip2" -version = "1.0.1+wasi-0.2.4" +version = "1.0.2+wasi-0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" +checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" dependencies = [ "wit-bindgen", ] [[package]] -name = "wasm-bindgen" -version = "0.2.100" +name = "wasip3" +version = "0.4.0+wasi-0.3.0-rc-2026-01-06" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" dependencies = [ - "cfg-if 1.0.0", - "once_cell", - "rustversion", - "wasm-bindgen-macro", + "wit-bindgen", ] [[package]] -name = "wasm-bindgen-backend" -version = "0.2.100" +name = "wasm-bindgen" +version = "0.2.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +checksum = "0551fc1bb415591e3372d0bc4780db7e587d84e2a7e79da121051c5c4b89d0b0" dependencies = [ - "bumpalo", - "log", - "proc-macro2", - "quote", - "syn", + "cfg-if 1.0.4", + "once_cell", + "rustversion", + "wasm-bindgen-macro", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.50" +version = "0.4.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" +checksum = "03623de6905b7206edd0a75f69f747f134b7f0a2323392d664448bf2d3c5d87e" dependencies = [ - "cfg-if 1.0.0", "js-sys", - "once_cell", "wasm-bindgen", - "web-sys", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.100" +version = "0.2.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +checksum = "7fbdf9a35adf44786aecd5ff89b4563a90325f9da0923236f6104e603c7e86be" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1900,31 +2071,65 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.100" +version = "0.2.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +checksum = "dca9693ef2bab6d4e6707234500350d8dad079eb508dca05530c85dc3a529ff2" dependencies = [ + "bumpalo", "proc-macro2", "quote", "syn", - "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.100" +version = "0.2.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +checksum = "39129a682a6d2d841b6c429d0c51e5cb0ed1a03829d8b3d1e69a011e62cb3d3b" dependencies = [ "unicode-ident", ] +[[package]] +name = "wasm-encoder" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" +dependencies = [ + "leb128fmt", + "wasmparser", +] + +[[package]] +name = "wasm-metadata" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" +dependencies = [ + "anyhow", + "indexmap 2.13.0", + "wasm-encoder", + "wasmparser", +] + +[[package]] +name = "wasmparser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" +dependencies = [ + "bitflags 2.11.0", + "hashbrown 0.15.5", + "indexmap 2.13.0", + "semver", +] + [[package]] name = "web-sys" -version = "0.3.77" +version = "0.3.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" +checksum = "cd70027e39b12f0849461e08ffc50b9cd7688d942c1c8e3c7b22273236b4dd0a" dependencies = [ "js-sys", "wasm-bindgen", @@ -1958,11 +2163,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.9" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -1995,15 +2200,6 @@ dependencies = [ "windows-targets 0.52.6", ] -[[package]] -name = "windows-sys" -version = "0.59.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets 0.52.6", -] - [[package]] name = "windows-sys" version = "0.61.2" @@ -2140,35 +2336,110 @@ version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" dependencies = [ - "cfg-if 1.0.0", + "cfg-if 1.0.4", "windows-sys 0.48.0", ] [[package]] name = "wit-bindgen" -version = "0.46.0" +version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" +checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" +dependencies = [ + "wit-bindgen-rust-macro", +] [[package]] -name = "write16" -version = "1.0.0" +name = "wit-bindgen-core" +version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" +checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" +dependencies = [ + "anyhow", + "heck", + "wit-parser", +] + +[[package]] +name = "wit-bindgen-rust" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" +dependencies = [ + "anyhow", + "heck", + "indexmap 2.13.0", + "prettyplease", + "syn", + "wasm-metadata", + "wit-bindgen-core", + "wit-component", +] + +[[package]] +name = "wit-bindgen-rust-macro" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" +dependencies = [ + "anyhow", + "prettyplease", + "proc-macro2", + "quote", + "syn", + "wit-bindgen-core", + "wit-bindgen-rust", +] + +[[package]] +name = "wit-component" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" +dependencies = [ + "anyhow", + "bitflags 2.11.0", + "indexmap 2.13.0", + "log", + "serde", + "serde_derive", + "serde_json", + "wasm-encoder", + "wasm-metadata", + "wasmparser", + "wit-parser", +] + +[[package]] +name = "wit-parser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" +dependencies = [ + "anyhow", + "id-arena", + "indexmap 2.13.0", + "log", + "semver", + "serde", + "serde_derive", + "serde_json", + "unicode-xid", + "wasmparser", +] [[package]] name = "writeable" -version = "0.5.5" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" +checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" [[package]] name = "yoke" -version = "0.7.5" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" +checksum = "abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca" dependencies = [ - "serde", "stable_deref_trait", "yoke-derive", "zerofrom", @@ -2176,9 +2447,9 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.7.5" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" +checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" dependencies = [ "proc-macro2", "quote", @@ -2188,18 +2459,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.7.35" +version = "0.8.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.35" +version = "0.8.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" dependencies = [ "proc-macro2", "quote", @@ -2208,18 +2479,18 @@ dependencies = [ [[package]] name = "zerofrom" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +checksum = "69faa1f2a1ea75661980b013019ed6687ed0e83d069bc1114e2cc74c6c04c4df" dependencies = [ "zerofrom-derive", ] [[package]] name = "zerofrom-derive" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" dependencies = [ "proc-macro2", "quote", @@ -2227,11 +2498,22 @@ dependencies = [ "synstructure", ] +[[package]] +name = "zerotrie" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + [[package]] name = "zerovec" -version = "0.10.4" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239" dependencies = [ "yoke", "zerofrom", @@ -2240,11 +2522,17 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.10.3" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" dependencies = [ "proc-macro2", "quote", "syn", ] + +[[package]] +name = "zmij" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" diff --git a/Cargo.toml b/Cargo.toml index 699d776..d35ee85 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,6 +2,7 @@ members = [ ".", "crates/gcno_reader", + "crates/trace_db_tools", ] [package] @@ -28,3 +29,5 @@ jsonschema = "0.17" indicatif = "0.18.0" rustc_data_structures = "0.1.2" inventory = "0.3" +rusqlite = { version = "0.31", features = ["bundled"] } +circular-buffer = "1.2.0" \ No newline at end of file diff --git a/configs/baremetal_hello/baremetal_boom_stress.json b/configs/baremetal_hello/baremetal_boom_stress.json new file mode 100644 index 0000000..373d49f --- /dev/null +++ b/configs/baremetal_hello/baremetal_boom_stress.json @@ -0,0 +1,12 @@ +{ + "encoded_trace": "../../sims/vcs/trace_monitor_boom_tile_0.encoded.trace", + "user_binaries": [], + "machine_binary": "../baremetal-ide/build/examples/pmu-tests/trace-stress.elf", + "kernel_binary": "", + "kernel_jump_label_patch_log": "", + "driver_binary_entry_tuples": [], + "receivers": { + "txt": { "enabled": true, "path": "trace.trace_stress.txt" }, + "speedscope": { "enabled": true, "path": "trace.trace_stress.speedscope.json" } + } +} \ No newline at end of file diff --git a/configs/embench/baremetal_wikisort.json b/configs/embench/baremetal_wikisort.json index 9676ced..953a2b9 100644 --- a/configs/embench/baremetal_wikisort.json +++ b/configs/embench/baremetal_wikisort.json @@ -6,31 +6,48 @@ "kernel_jump_label_patch_log": "", "driver_binary_entry_tuples": [], "receivers": { - "reference_bb": { - "enabled": false, - "path": "trace.trace_wikisort.reference_bb.csv" + "tnt_cyc_nret_bb_emulation": { + "enabled": true, + "path": "trace.trace_wikisort.tnt_cyc_nret_bb_emulation.csv", + "lim_tnt": 47 }, - "reference_func": { - "enabled": false, - "path": "trace.trace_wikisort.reference_func.csv" + "tnt_cyc_retcompressed_bb_emulation": { + "enabled": true, + "path": "trace.trace_wikisort.tnt_cyc_retcompressed_bb_emulation.csv", + "lim_tnt": 47 }, "tc_bb_emulation": { - "enabled": false, + "enabled": true, "path": "trace.trace_wikisort.tc_bb_emulation.csv", "interval": 1000 }, - "cyc_bb_emulation": { - "enabled": false, - "path": "trace.trace_wikisort.cyc_bb_emulation.csv", - "lim_tnt": 6 + "tnt_cyc_nret_func_emulation": { + "enabled": true, + "path": "trace.trace_wikisort.tnt_cyc_nret_func_emulation.csv", + "dump_csv": true, + "lim_tnt": 47 }, - "cyc_func_emulation": { - "enabled": false, - "path": "trace.trace_wikisort.cyc_func_emulation.csv", - "lim_tnt": 6 + "tnt_cyc_retcompressed_func_emulation": { + "enabled": true, + "path": "trace.trace_wikisort.tnt_cyc_retcompressed_func_emulation.csv", + "lim_tnt": 47 }, - "speedscope": { + "tc_func_emulation": { "enabled": true, + "path": "trace.trace_wikisort.tc_func_emulation.csv", + "interval": 1000 + }, + "cyc_func_emulation_old": { + "enabled": true, + "path": "trace.trace_wikisort.cyc_func_emulation_old.csv", + "lim_tnt": 47 + }, + "reference_func_old": { + "enabled": true, + "path": "trace.trace_wikisort.reference_func_old.csv" + }, + "speedscope": { + "enabled": false, "path": "trace.trace_wikisort.speedscope.json" } } diff --git a/configs/linux/linux_ipi_storm_0.json b/configs/linux/linux_ipi_storm_0.json new file mode 100644 index 0000000..9308313 --- /dev/null +++ b/configs/linux/linux_ipi_storm_0.json @@ -0,0 +1,60 @@ +{ + "encoded_trace": "/scratch/iansseijelly/interesting_profile/ipi_storm.tacit0.out", + "user_binaries": [ + { + "binary": "../firemarshal/example-workloads/ipi-storm/overlay/root/ipi-storm/trace-submit", + "asids": [ + 106, + 107 + ] + }, + { + "binary": "../firemarshal/example-workloads/ipi-storm/overlay/root/ipi-storm/hello", + "asids": [ + 108 + ] + } + ], + "machine_binary": "../firemarshal/images/firechip/ipi-storm/ipi-storm-bin", + "kernel_binary": "../firemarshal/images/firechip/ipi-storm/ipi-storm-bin-dwarf", + "kernel_jump_label_patch_log": "/scratch/iansseijelly/tacit-chipyard/sims/firesim/deploy/results-workload/2026-03-29--21-38-08-ipi-storm/ipi-storm-run-chores/jump_label_patch_map.txt", + "driver_binary_entry_tuples": [ + [ + "../firemarshal/images/firechip/ipi-storm/tacit-dwarf", + "0xffffffff01b08000" + ], + [ + "../firemarshal/images/firechip/ipi-storm/iceblk-dwarf", + "0xffffffff01b88000" + ] + ], + "receivers": { + "txt": { + "enabled": false, + "path": "trace.ipi_storm_0.txt" + }, + "prv_breakdown": { + "enabled": false + }, + "speedscope": { + "enabled": false, + "path": "trace.ipi_storm_0.speedscope.json" + }, + "bb_stats": { + "enabled": false, + "path": "trace.bb_stats.csv", + "do_supervisor": true + }, + "sqlite": { + "enabled": false, + "path": "trace.db" + }, + "func_path": { + "enabled": true, + "path": "trace.ipi_storm_0.func_path.csv", + "func_name": "_trap_handler", + "ctx": 108, + "filter_contains": "sbi_tlb_request" + } + } +} \ No newline at end of file diff --git a/configs/linux/linux_ipi_storm_1.json b/configs/linux/linux_ipi_storm_1.json new file mode 100644 index 0000000..5c1f482 --- /dev/null +++ b/configs/linux/linux_ipi_storm_1.json @@ -0,0 +1,62 @@ +{ + "encoded_trace": "/scratch/iansseijelly/interesting_profile/ipi_storm.tacit1.out", + "user_binaries": [ + { + "binary": "../firemarshal/example-workloads/ipi-storm/overlay/root/ipi-storm/trace-submit", + "asids": [ + 106, + 107 + ] + }, + { + "binary": "../firemarshal/example-workloads/ipi-storm/overlay/root/ipi-storm/hello", + "asids": [ + 108 + ] + } + ], + "machine_binary": "../firemarshal/images/firechip/ipi-storm/ipi-storm-bin", + "kernel_binary": "../firemarshal/images/firechip/ipi-storm/ipi-storm-bin-dwarf", + "kernel_jump_label_patch_log": "/scratch/iansseijelly/tacit-chipyard/sims/firesim/deploy/results-workload/2026-03-29--21-38-08-ipi-storm/ipi-storm-run-chores/jump_label_patch_map.txt", + "driver_binary_entry_tuples": [ + [ + "../firemarshal/images/firechip/ipi-storm/tacit-dwarf", + "0xffffffff01b08000" + ], + [ + "../firemarshal/images/firechip/ipi-storm/iceblk-dwarf", + "0xffffffff01b88000" + ] + ], + "receivers": { + "txt": { + "enabled": true, + "path": "trace.ipi_storm_1.txt" + }, + "prv_breakdown": { + "enabled": false + }, + "speedscope": { + "enabled": false, + "path": "trace.ipi_storm_1.speedscope.json" + }, + "bb_stats": { + "enabled": false, + "path": "trace.bb_stats.csv", + "do_supervisor": true + }, + "sqlite": { + "enabled": false, + "path": "trace.db" + }, + "func_path": { + "enabled": true, + "path": "trace.ipi_storm_1.func_path.csv", + "func_name": "_trap_handler", + "ctx": 108, + "filter_contains": "tlb_process", + "post_exit_path": "trace.ipi_storm_1.func_path.post_exit.csv", + "post_exit_n": 10 + } + } +} \ No newline at end of file diff --git a/configs/linux/linux_process_launch.json b/configs/linux/linux_process_launch.json index 45d8333..0f17152 100644 --- a/configs/linux/linux_process_launch.json +++ b/configs/linux/linux_process_launch.json @@ -10,44 +10,76 @@ { "binary": "../firemarshal/example-workloads/process-launch/overlay/root/process-launch/dummy", "asids": [ - 1077, - 1078, - 1079, - 1080, - 1081, - 1082, - 1083, - 1084, - 1085, - 1086, - 1087, - 1088, - 1089, - 1090, - 1091, - 1092, - 1093, - 1094, - 1095, - 1096, - 1097, - 1098, - 1099, - 1100, - 1101, - 1102, - 1103, - 1104, - 1105, - 1106, - 1107, - 1108 + 977, + 978, + 979, + 980, + 981, + 982, + 983, + 984, + 985, + 986, + 987, + 988, + 989, + 990, + 991, + 992, + 993, + 994, + 995, + 996, + 997, + 998, + 999, + 1000, + 1001, + 1002, + 1003, + 1004, + 1005, + 1006, + 1007, + 1008, + 1009, + 1010, + 1011, + 1012, + 1013, + 1014, + 1015, + 1016, + 1017, + 1018, + 1019, + 1020, + 1021, + 1022, + 1023, + 1024, + 1025, + 1026, + 1027, + 1028, + 1029, + 1030, + 1031, + 1032, + 1033, + 1034, + 1035, + 1036, + 1037, + 1038, + 1039, + 1040 ] } ], "machine_binary": "../firemarshal/images/firechip/process-launch/process-launch-bin", "kernel_binary": "../firemarshal/images/firechip/process-launch/process-launch-bin-dwarf", - "kernel_jump_label_patch_log": "/scratch/iansseijelly/tacit-chipyard/sims/firesim/deploy/results-workload/2026-02-18--00-01-56-trace-hello/trace-hello-run-chores/jump_label_patch_map.txt", + "kernel_jump_label_patch_log": "/scratch/iansseijelly/tacit-chipyard/sims/firesim/deploy/results-workload/2026-03-29--21-38-08-ipi-storm/ipi-storm-run-chores/jump_label_patch_map.txt", "driver_binary_entry_tuples": [ [ "../firemarshal/images/firechip/process-launch/tacit-dwarf", @@ -55,25 +87,35 @@ ], [ "../firemarshal/images/firechip/process-launch/iceblk-dwarf", - "0xffffffff01b6b000" + "0xffffffff01b88000" ] ], "receivers": { "txt": { - "enabled": true, - "path": "trace.test.txt" + "enabled": false, + "path": "trace.process-launch.txt" }, "prv_breakdown": { "enabled": true }, "speedscope": { "enabled": true, - "path": "trace.speedscope.json" + "path": "trace.process-launch.speedscope.json" }, "bb_stats": { "enabled": false, "path": "trace.bb_stats.csv", "do_supervisor": true + }, + "iteration_breakdown": { + "enabled": true, + "marker_func": "syscall", + "tracked_func": "rcu_do_batch", + "path": "trace.iteration_breakdown.csv" + }, + "sqlite": { + "enabled": false, + "path": "trace.db" } } } \ No newline at end of file diff --git a/configs/spec-emulation/linux_600_perlbench.json b/configs/spec-emulation/linux_600_perlbench.json new file mode 100644 index 0000000..e4dd939 --- /dev/null +++ b/configs/spec-emulation/linux_600_perlbench.json @@ -0,0 +1,97 @@ +{ + "encoded_trace": "/scratch/iansseijelly/interesting_profile/spec17-intspeed-traced-wave1-600.perlbench_s.out", + "user_binaries": [ + { + "binary": "../spec2017/speckle/build/overlay/intspeed/test/600.perlbench_s/perlbench_s_base.riscv-64", + "asids": [ + 117, + 121, + 123, + 124, + 125, + 127, + 129, + 131, + 133, + 135, + 137, + 139, + 141, + 143, + 145, + 147, + 149, + 151, + 153, + 156, + 157, + 159, + 161, + 163, + 165, + 167, + 169, + 171, + 173, + 175, + 177, + 179, + 181, + 182, + 183, + 185, + 187, + 189, + 191, + 193, + 195, + 197 + ] + } + ], + "machine_binary": "../firemarshal/images/firechip/spec17-intspeed-traced-wave1-600.perlbench_s-traced/spec17-intspeed-traced-wave1-600.perlbench_s-traced-bin", + "kernel_binary": "../firemarshal/images/firechip/spec17-intspeed-traced-wave1-600.perlbench_s-traced/spec17-intspeed-traced-wave1-600.perlbench_s-traced-bin-dwarf", + "kernel_jump_label_patch_log": "/scratch/iansseijelly/tacit-chipyard/sims/firesim/deploy/results-workload/2026-03-20--06-42-57-spec-chores/spec-chores-run-chores/jump_label_patch_map.txt", + "driver_binary_entry_tuples": [ + [ + "../firemarshal/boards/firechip/drivers/tacit-driver/tacit.o", + "0xffffffff01b08000" + ], + [ + "../firemarshal/boards/firechip/drivers/iceblk-driver/iceblk.o", + "0xffffffff01b88000" + ] + ], + "receivers": { + "tnt_cyc_nret_bb_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tnt_cyc_nret_bb_emulation.csv", + "lim_tnt": 47 + }, + "tnt_cyc_retcompressed_bb_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tnt_cyc_retcompressed_bb_emulation.csv", + "lim_tnt": 47 + }, + "tc_bb_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tc_bb_emulation.csv", + "interval": 1000 + }, + "tnt_cyc_nret_func_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tnt_cyc_nret_func_emulation.csv", + "lim_tnt": 47 + }, + "tnt_cyc_retcompressed_func_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tnt_cyc_retcompressed_func_emulation.csv", + "lim_tnt": 47 + }, + "tc_func_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tc_func_emulation.csv", + "interval": 1000 + } + } +} diff --git a/configs/spec-emulation/linux_602_gcc.json b/configs/spec-emulation/linux_602_gcc.json new file mode 100644 index 0000000..8900b5e --- /dev/null +++ b/configs/spec-emulation/linux_602_gcc.json @@ -0,0 +1,54 @@ +{ + "encoded_trace": "/scratch/iansseijelly/interesting_profile/spec17-intspeed-traced-wave1-602.gcc_s.out", + "user_binaries": [ + { + "binary": "../spec2017/speckle/build/overlay/intspeed/test/602.gcc_s/sgcc_base.riscv-64", + "asids": [117] + } + ], + "machine_binary": "../firemarshal/images/firechip/spec17-intspeed-test-602-602.gcc_s/spec17-intspeed-test-602-602.gcc_s-bin", + "kernel_binary": "../firemarshal/images/firechip/spec17-intspeed-test-602-602.gcc_s/spec17-intspeed-test-602-602.gcc_s-bin-dwarf", + "kernel_jump_label_patch_log": "/scratch/iansseijelly/tacit-chipyard/sims/firesim/deploy/results-workload/2026-03-20--06-42-57-spec-chores/spec-chores-run-chores/jump_label_patch_map.txt", + "driver_binary_entry_tuples": [ + [ + "../firemarshal/boards/firechip/drivers/tacit-driver/tacit.o", + "0xffffffff01b08000" + ], + [ + "../firemarshal/boards/firechip/drivers/iceblk-driver/iceblk.o", + "0xffffffff01b88000" + ] + ], + "receivers": { + "tnt_cyc_nret_bb_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tnt_cyc_nret_bb_emulation.csv", + "lim_tnt": 47 + }, + "tnt_cyc_retcompressed_bb_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tnt_cyc_retcompressed_bb_emulation.csv", + "lim_tnt": 47 + }, + "tc_bb_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tc_bb_emulation.csv", + "interval": 1000 + }, + "tnt_cyc_nret_func_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tnt_cyc_nret_func_emulation.csv", + "lim_tnt": 47 + }, + "tnt_cyc_retcompressed_func_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tnt_cyc_retcompressed_func_emulation.csv", + "lim_tnt": 47 + }, + "tc_func_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tc_func_emulation.csv", + "interval": 1000 + } + } +} diff --git a/configs/spec-emulation/linux_605_mcf.json b/configs/spec-emulation/linux_605_mcf.json new file mode 100644 index 0000000..10cea8e --- /dev/null +++ b/configs/spec-emulation/linux_605_mcf.json @@ -0,0 +1,54 @@ +{ + "encoded_trace": "/scratch/iansseijelly/FIRESIM_RUN_TMP/sim_slot_1/tacit0.out", + "user_binaries": [ + { + "binary": "../spec2017/speckle/build/overlay/intspeed/test/605.mcf_s/mcf_s_base.riscv-64", + "asids": [117] + } + ], + "machine_binary": "../firemarshal/images/firechip/spec17-intspeed-traced-wave1-600.perlbench_s-traced/spec17-intspeed-traced-wave1-600.perlbench_s-traced-bin", + "kernel_binary": "../firemarshal/images/firechip/spec17-intspeed-traced-wave1-600.perlbench_s-traced/spec17-intspeed-traced-wave1-600.perlbench_s-traced-bin-dwarf", + "kernel_jump_label_patch_log": "/scratch/iansseijelly/tacit-chipyard/sims/firesim/deploy/results-workload/2026-03-20--06-42-57-spec-chores/spec-chores-run-chores/jump_label_patch_map.txt", + "driver_binary_entry_tuples": [ + [ + "../firemarshal/boards/firechip/drivers/tacit-driver/tacit.o", + "0xffffffff01b08000" + ], + [ + "../firemarshal/boards/firechip/drivers/iceblk-driver/iceblk.o", + "0xffffffff01b88000" + ] + ], + "receivers": { + "tnt_cyc_nret_bb_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tnt_cyc_nret_bb_emulation.csv", + "lim_tnt": 47 + }, + "tnt_cyc_retcompressed_bb_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tnt_cyc_retcompressed_bb_emulation.csv", + "lim_tnt": 47 + }, + "tc_bb_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tc_bb_emulation.csv", + "interval": 1000 + }, + "tnt_cyc_nret_func_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tnt_cyc_nret_func_emulation.csv", + "lim_tnt": 47 + }, + "tnt_cyc_retcompressed_func_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tnt_cyc_retcompressed_func_emulation.csv", + "lim_tnt": 47 + }, + "tc_func_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tc_func_emulation.csv", + "interval": 1000 + } + } +} diff --git a/configs/spec-emulation/linux_620_omnetpp.json b/configs/spec-emulation/linux_620_omnetpp.json new file mode 100644 index 0000000..75bc17d --- /dev/null +++ b/configs/spec-emulation/linux_620_omnetpp.json @@ -0,0 +1,54 @@ +{ + "encoded_trace": "/scratch/iansseijelly/interesting_profile/spec17-intspeed-traced-wave1-620.omnetpp_s.out", + "user_binaries": [ + { + "binary": "../spec2017/speckle/build/overlay/intspeed/test/620.omnetpp_s/omnetpp_s_base.riscv-64", + "asids": [117] + } + ], + "machine_binary": "../firemarshal/images/firechip/spec17-intspeed-traced-wave1-600.perlbench_s-traced/spec17-intspeed-traced-wave1-600.perlbench_s-traced-bin", + "kernel_binary": "../firemarshal/images/firechip/spec17-intspeed-traced-wave1-600.perlbench_s-traced/spec17-intspeed-traced-wave1-600.perlbench_s-traced-bin-dwarf", + "kernel_jump_label_patch_log": "/scratch/iansseijelly/tacit-chipyard/sims/firesim/deploy/results-workload/2026-03-20--06-42-57-spec-chores/spec-chores-run-chores/jump_label_patch_map.txt", + "driver_binary_entry_tuples": [ + [ + "../firemarshal/boards/firechip/drivers/tacit-driver/tacit.o", + "0xffffffff01b08000" + ], + [ + "../firemarshal/boards/firechip/drivers/iceblk-driver/iceblk.o", + "0xffffffff01b88000" + ] + ], + "receivers": { + "tnt_cyc_nret_bb_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tnt_cyc_nret_bb_emulation.csv", + "lim_tnt": 47 + }, + "tnt_cyc_retcompressed_bb_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tnt_cyc_retcompressed_bb_emulation.csv", + "lim_tnt": 47 + }, + "tc_bb_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tc_bb_emulation.csv", + "interval": 1000 + }, + "tnt_cyc_nret_func_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tnt_cyc_nret_func_emulation.csv", + "lim_tnt": 47 + }, + "tnt_cyc_retcompressed_func_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tnt_cyc_retcompressed_func_emulation.csv", + "lim_tnt": 47 + }, + "tc_func_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tc_func_emulation.csv", + "interval": 1000 + } + } +} diff --git a/configs/spec-emulation/linux_623_xalancbmk.json b/configs/spec-emulation/linux_623_xalancbmk.json new file mode 100644 index 0000000..1ea6841 --- /dev/null +++ b/configs/spec-emulation/linux_623_xalancbmk.json @@ -0,0 +1,54 @@ +{ + "encoded_trace": "/scratch/iansseijelly/interesting_profile/spec17-intspeed-traced-wave1-623.xalancbmk_s.out", + "user_binaries": [ + { + "binary": "../spec2017/speckle/build/overlay/intspeed/test/623.xalancbmk_s/xalancbmk_s_base.riscv-64", + "asids": [117] + } + ], + "machine_binary": "../firemarshal/images/firechip/spec17-intspeed-traced-wave1-600.perlbench_s-traced/spec17-intspeed-traced-wave1-600.perlbench_s-traced-bin", + "kernel_binary": "../firemarshal/images/firechip/spec17-intspeed-traced-wave1-600.perlbench_s-traced/spec17-intspeed-traced-wave1-600.perlbench_s-traced-bin-dwarf", + "kernel_jump_label_patch_log": "/scratch/iansseijelly/tacit-chipyard/sims/firesim/deploy/results-workload/2026-03-20--06-42-57-spec-chores/spec-chores-run-chores/jump_label_patch_map.txt", + "driver_binary_entry_tuples": [ + [ + "../firemarshal/boards/firechip/drivers/tacit-driver/tacit.o", + "0xffffffff01b08000" + ], + [ + "../firemarshal/boards/firechip/drivers/iceblk-driver/iceblk.o", + "0xffffffff01b88000" + ] + ], + "receivers": { + "tnt_cyc_nret_bb_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tnt_cyc_nret_bb_emulation.csv", + "lim_tnt": 47 + }, + "tnt_cyc_retcompressed_bb_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tnt_cyc_retcompressed_bb_emulation.csv", + "lim_tnt": 47 + }, + "tc_bb_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tc_bb_emulation.csv", + "interval": 1000 + }, + "tnt_cyc_nret_func_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tnt_cyc_nret_func_emulation.csv", + "lim_tnt": 47 + }, + "tnt_cyc_retcompressed_func_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tnt_cyc_retcompressed_func_emulation.csv", + "lim_tnt": 47 + }, + "tc_func_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tc_func_emulation.csv", + "interval": 1000 + } + } +} diff --git a/configs/spec-emulation/linux_625_x264.json b/configs/spec-emulation/linux_625_x264.json new file mode 100644 index 0000000..bf0a0c4 --- /dev/null +++ b/configs/spec-emulation/linux_625_x264.json @@ -0,0 +1,54 @@ +{ + "encoded_trace": "/scratch/iansseijelly/interesting_profile/spec17-intspeed-traced-wave1-625.x264_s.out", + "user_binaries": [ + { + "binary": "../spec2017/speckle/build/overlay/intspeed/test/625.x264_s/x264_s_base.riscv-64", + "asids": [117] + } + ], + "machine_binary": "../firemarshal/images/firechip/spec17-intspeed-traced-wave1-600.perlbench_s-traced/spec17-intspeed-traced-wave1-600.perlbench_s-traced-bin", + "kernel_binary": "../firemarshal/images/firechip/spec17-intspeed-traced-wave1-600.perlbench_s-traced/spec17-intspeed-traced-wave1-600.perlbench_s-traced-bin-dwarf", + "kernel_jump_label_patch_log": "/scratch/iansseijelly/tacit-chipyard/sims/firesim/deploy/results-workload/2026-03-20--06-42-57-spec-chores/spec-chores-run-chores/jump_label_patch_map.txt", + "driver_binary_entry_tuples": [ + [ + "../firemarshal/boards/firechip/drivers/tacit-driver/tacit.o", + "0xffffffff01b08000" + ], + [ + "../firemarshal/boards/firechip/drivers/iceblk-driver/iceblk.o", + "0xffffffff01b88000" + ] + ], + "receivers": { + "tnt_cyc_nret_bb_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tnt_cyc_nret_bb_emulation.csv", + "lim_tnt": 47 + }, + "tnt_cyc_retcompressed_bb_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tnt_cyc_retcompressed_bb_emulation.csv", + "lim_tnt": 47 + }, + "tc_bb_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tc_bb_emulation.csv", + "interval": 1000 + }, + "tnt_cyc_nret_func_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tnt_cyc_nret_func_emulation.csv", + "lim_tnt": 47 + }, + "tnt_cyc_retcompressed_func_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tnt_cyc_retcompressed_func_emulation.csv", + "lim_tnt": 47 + }, + "tc_func_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tc_func_emulation.csv", + "interval": 1000 + } + } +} diff --git a/configs/spec-emulation/linux_631_deepsjeng.json b/configs/spec-emulation/linux_631_deepsjeng.json new file mode 100644 index 0000000..be0e944 --- /dev/null +++ b/configs/spec-emulation/linux_631_deepsjeng.json @@ -0,0 +1,45 @@ +{ + "encoded_trace": "/scratch/iansseijelly/FIRESIM_RUN_TMP/sim_slot_0/tacit0.out", + "user_binaries": [ + {"binary": "../spec2017/speckle/build/overlay/intspeed/test/631.deepsjeng_s/deepsjeng_s_base.riscv-64", "asids": [117]} + ], + "machine_binary": "../firemarshal/images/firechip/spec17-intspeed-test-631-631.deepsjeng_s/spec17-intspeed-test-631-631.deepsjeng_s-bin", + "kernel_binary": "../firemarshal/images/firechip/spec17-intspeed-test-631-631.deepsjeng_s/spec17-intspeed-test-631-631.deepsjeng_s-bin-dwarf", + "kernel_jump_label_patch_log": "/scratch/iansseijelly/tacit-chipyard/sims/firesim/deploy/results-workload/2025-11-15--01-13-55-spec17-intspeed-test-605/spec17-intspeed-test-605-run-chores/jump_label_patch_map.txt", + "driver_binary_entry_tuples": [ + ["../firemarshal/boards/firechip/drivers/tacit-driver/tacit.o", "0xffffffff0169d000"], + ["../firemarshal/boards/firechip/drivers/iceblk-driver/iceblk.o", "0xffffffff016ac000"] + ], + "receivers": { + "tnt_cyc_nret_bb_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tnt_cyc_nret_bb_emulation.csv", + "lim_tnt": 47 + }, + "tnt_cyc_retcompressed_bb_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tnt_cyc_retcompressed_bb_emulation.csv", + "lim_tnt": 47 + }, + "tc_bb_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tc_bb_emulation.csv", + "interval": 1000 + }, + "tnt_cyc_nret_func_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tnt_cyc_nret_func_emulation.csv", + "lim_tnt": 47 + }, + "tnt_cyc_retcompressed_func_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tnt_cyc_retcompressed_func_emulation.csv", + "lim_tnt": 47 + }, + "tc_func_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tc_func_emulation.csv", + "interval": 1000 + } + } +} diff --git a/configs/spec-emulation/linux_641_leela.json b/configs/spec-emulation/linux_641_leela.json new file mode 100644 index 0000000..7bd2ff9 --- /dev/null +++ b/configs/spec-emulation/linux_641_leela.json @@ -0,0 +1,54 @@ +{ + "encoded_trace": "/scratch/iansseijelly/interesting_profile/spec17-intspeed-traced-wave2-641.leela_s.out", + "user_binaries": [ + { + "binary": "../spec2017/speckle/build/overlay/intspeed/test/641.leela_s/leela_s_base.riscv-64", + "asids": [117] + } + ], + "machine_binary": "../firemarshal/images/firechip/spec17-intspeed-traced-wave1-600.perlbench_s-traced/spec17-intspeed-traced-wave1-600.perlbench_s-traced-bin", + "kernel_binary": "../firemarshal/images/firechip/spec17-intspeed-traced-wave1-600.perlbench_s-traced/spec17-intspeed-traced-wave1-600.perlbench_s-traced-bin-dwarf", + "kernel_jump_label_patch_log": "/scratch/iansseijelly/tacit-chipyard/sims/firesim/deploy/results-workload/2026-03-20--06-42-57-spec-chores/spec-chores-run-chores/jump_label_patch_map.txt", + "driver_binary_entry_tuples": [ + [ + "../firemarshal/boards/firechip/drivers/tacit-driver/tacit.o", + "0xffffffff01b08000" + ], + [ + "../firemarshal/boards/firechip/drivers/iceblk-driver/iceblk.o", + "0xffffffff01aa7000" + ] + ], + "receivers": { + "tnt_cyc_nret_bb_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tnt_cyc_nret_bb_emulation.csv", + "lim_tnt": 47 + }, + "tnt_cyc_retcompressed_bb_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tnt_cyc_retcompressed_bb_emulation.csv", + "lim_tnt": 47 + }, + "tc_bb_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tc_bb_emulation.csv", + "interval": 1000 + }, + "tnt_cyc_nret_func_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tnt_cyc_nret_func_emulation.csv", + "lim_tnt": 47 + }, + "tnt_cyc_retcompressed_func_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tnt_cyc_retcompressed_func_emulation.csv", + "lim_tnt": 47 + }, + "tc_func_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tc_func_emulation.csv", + "interval": 1000 + } + } +} diff --git a/configs/spec-emulation/linux_648_exchange2.json b/configs/spec-emulation/linux_648_exchange2.json new file mode 100644 index 0000000..4c2fef0 --- /dev/null +++ b/configs/spec-emulation/linux_648_exchange2.json @@ -0,0 +1,54 @@ +{ + "encoded_trace": "/scratch/iansseijelly/interesting_profile/spec17-intspeed-traced-wave2-648.exchange2_s.out", + "user_binaries": [ + { + "binary": "../spec2017/speckle/build/overlay/intspeed/test/648.exchange2_s/exchange2_s_base.riscv-64", + "asids": [117] + } + ], + "machine_binary": "../firemarshal/images/firechip/spec17-intspeed-traced-wave1-600.perlbench_s-traced/spec17-intspeed-traced-wave1-600.perlbench_s-traced-bin", + "kernel_binary": "../firemarshal/images/firechip/spec17-intspeed-traced-wave1-600.perlbench_s-traced/spec17-intspeed-traced-wave1-600.perlbench_s-traced-bin-dwarf", + "kernel_jump_label_patch_log": "/scratch/iansseijelly/tacit-chipyard/sims/firesim/deploy/results-workload/2026-03-20--06-42-57-spec-chores/spec-chores-run-chores/jump_label_patch_map.txt", + "driver_binary_entry_tuples": [ + [ + "../firemarshal/boards/firechip/drivers/tacit-driver/tacit.o", + "0xffffffff01b08000" + ], + [ + "../firemarshal/boards/firechip/drivers/iceblk-driver/iceblk.o", + "0xffffffff01b88000" + ] + ], + "receivers": { + "tnt_cyc_nret_bb_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tnt_cyc_nret_bb_emulation.csv", + "lim_tnt": 47 + }, + "tnt_cyc_retcompressed_bb_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tnt_cyc_retcompressed_bb_emulation.csv", + "lim_tnt": 47 + }, + "tc_bb_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tc_bb_emulation.csv", + "interval": 1000 + }, + "tnt_cyc_nret_func_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tnt_cyc_nret_func_emulation.csv", + "lim_tnt": 47 + }, + "tnt_cyc_retcompressed_func_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tnt_cyc_retcompressed_func_emulation.csv", + "lim_tnt": 47 + }, + "tc_func_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tc_func_emulation.csv", + "interval": 1000 + } + } +} diff --git a/configs/spec-emulation/linux_657_xz_cld.json b/configs/spec-emulation/linux_657_xz_cld.json new file mode 100644 index 0000000..f064af6 --- /dev/null +++ b/configs/spec-emulation/linux_657_xz_cld.json @@ -0,0 +1,54 @@ +{ + "encoded_trace": "/scratch/iansseijelly/interesting_profile/spec17-intspeed-traced-wave2-657.xz_s-cld.out", + "user_binaries": [ + { + "binary": "../spec2017/speckle/build/overlay/intspeed/test/657.xz_s/xz_s_base.riscv-64", + "asids": [117] + } + ], + "machine_binary": "../firemarshal/images/firechip/spec17-intspeed-traced-wave1-600.perlbench_s-traced/spec17-intspeed-traced-wave1-600.perlbench_s-traced-bin", + "kernel_binary": "../firemarshal/images/firechip/spec17-intspeed-traced-wave1-600.perlbench_s-traced/spec17-intspeed-traced-wave1-600.perlbench_s-traced-bin-dwarf", + "kernel_jump_label_patch_log": "/scratch/iansseijelly/tacit-chipyard/sims/firesim/deploy/results-workload/2026-03-20--06-42-57-spec-chores/spec-chores-run-chores/jump_label_patch_map.txt", + "driver_binary_entry_tuples": [ + [ + "../firemarshal/boards/firechip/drivers/tacit-driver/tacit.o", + "0xffffffff01b08000" + ], + [ + "../firemarshal/boards/firechip/drivers/iceblk-driver/iceblk.o", + "0xffffffff01b88000" + ] + ], + "receivers": { + "tnt_cyc_nret_bb_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tnt_cyc_nret_bb_emulation.csv", + "lim_tnt": 47 + }, + "tnt_cyc_retcompressed_bb_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tnt_cyc_retcompressed_bb_emulation.csv", + "lim_tnt": 47 + }, + "tc_bb_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tc_bb_emulation.csv", + "interval": 1000 + }, + "tnt_cyc_nret_func_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tnt_cyc_nret_func_emulation.csv", + "lim_tnt": 47 + }, + "tnt_cyc_retcompressed_func_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tnt_cyc_retcompressed_func_emulation.csv", + "lim_tnt": 47 + }, + "tc_func_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tc_func_emulation.csv", + "interval": 1000 + } + } +} diff --git a/configs/spec-emulation/linux_657_xz_cpu2006docs.json b/configs/spec-emulation/linux_657_xz_cpu2006docs.json new file mode 100644 index 0000000..3135c0b --- /dev/null +++ b/configs/spec-emulation/linux_657_xz_cpu2006docs.json @@ -0,0 +1,54 @@ +{ + "encoded_trace": "/scratch/iansseijelly/interesting_profile/spec17-intspeed-traced-wave2-657.xz_s-cpu2006docs.out", + "user_binaries": [ + { + "binary": "../spec2017/speckle/build/overlay/intspeed/test/657.xz_s/xz_s_base.riscv-64", + "asids": [117] + } + ], + "machine_binary": "../firemarshal/images/firechip/spec17-intspeed-traced-wave1-600.perlbench_s-traced/spec17-intspeed-traced-wave1-600.perlbench_s-traced-bin", + "kernel_binary": "../firemarshal/images/firechip/spec17-intspeed-traced-wave1-600.perlbench_s-traced/spec17-intspeed-traced-wave1-600.perlbench_s-traced-bin-dwarf", + "kernel_jump_label_patch_log": "/scratch/iansseijelly/tacit-chipyard/sims/firesim/deploy/results-workload/2026-03-20--06-42-57-spec-chores/spec-chores-run-chores/jump_label_patch_map.txt", + "driver_binary_entry_tuples": [ + [ + "../firemarshal/boards/firechip/drivers/tacit-driver/tacit.o", + "0xffffffff01b08000" + ], + [ + "../firemarshal/boards/firechip/drivers/iceblk-driver/iceblk.o", + "0xffffffff01b88000" + ] + ], + "receivers": { + "tnt_cyc_nret_bb_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tnt_cyc_nret_bb_emulation.csv", + "lim_tnt": 47 + }, + "tnt_cyc_retcompressed_bb_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tnt_cyc_retcompressed_bb_emulation.csv", + "lim_tnt": 47 + }, + "tc_bb_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tc_bb_emulation.csv", + "interval": 1000 + }, + "tnt_cyc_nret_func_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tnt_cyc_nret_func_emulation.csv", + "lim_tnt": 47 + }, + "tnt_cyc_retcompressed_func_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tnt_cyc_retcompressed_func_emulation.csv", + "lim_tnt": 47 + }, + "tc_func_emulation": { + "enabled": true, + "path": "trace.trace_perlbench.tc_func_emulation.csv", + "interval": 1000 + } + } +} diff --git a/configs/spec/linux_600_perlbench.json b/configs/spec/linux_600_perlbench.json index 5b269c3..97d5053 100644 --- a/configs/spec/linux_600_perlbench.json +++ b/configs/spec/linux_600_perlbench.json @@ -1,14 +1,80 @@ { - "encoded_trace": "/scratch/iansseijelly/FIRESIM_RUN_TMP/sim_slot_0/tacit0.out", - "user_binaries": [], - "machine_binary": "../firemarshal/images/firechip/spec17-intspeed-test-600.perlbench_s/spec17-intspeed-test-600.perlbench_s-bin", - "kernel_binary": "../firemarshal/images/firechip/spec17-intspeed-test-600.perlbench_s/spec17-intspeed-test-600.perlbench_s-bin-dwarf", - "kernel_jump_label_patch_log": "/scratch/iansseijelly/tacit-chipyard/sims/firesim/deploy/results-workload/2025-11-15--01-13-55-spec17-intspeed-test-605/spec17-intspeed-test-605-run-chores/jump_label_patch_map.txt", + "encoded_trace": "/scratch/iansseijelly/interesting_profile/spec17-intspeed-traced-wave1-600.perlbench_s.out", + "user_binaries": [ + { + "binary": "../spec2017/speckle/build/overlay/intspeed/test/600.perlbench_s/perlbench_s_base.riscv-64", + "asids": [ + 117, + 121, + 123, + 124, + 125, + 127, + 129, + 131, + 133, + 135, + 137, + 139, + 141, + 143, + 145, + 147, + 149, + 151, + 153, + 156, + 157, + 159, + 161, + 163, + 165, + 167, + 169, + 171, + 173, + 175, + 177, + 179, + 181, + 182, + 183, + 185, + 187, + 189, + 191, + 193, + 195, + 197 + ] + } + ], + "machine_binary": "../firemarshal/images/firechip/spec17-intspeed-traced-wave1-600.perlbench_s-traced/spec17-intspeed-traced-wave1-600.perlbench_s-traced-bin", + "kernel_binary": "../firemarshal/images/firechip/spec17-intspeed-traced-wave1-600.perlbench_s-traced/spec17-intspeed-traced-wave1-600.perlbench_s-traced-bin-dwarf", + "kernel_jump_label_patch_log": "/scratch/iansseijelly/tacit-chipyard/sims/firesim/deploy/results-workload/2026-03-20--06-42-57-spec-chores/spec-chores-run-chores/jump_label_patch_map.txt", "driver_binary_entry_tuples": [ - ["../firemarshal/boards/firechip/drivers/tacit-driver/tacit.o", "0xffffffff0169d000"], - ["../firemarshal/boards/firechip/drivers/iceblk-driver/iceblk.o", "0xffffffff016ac000"] + [ + "../firemarshal/boards/firechip/drivers/tacit-driver/tacit.o", + "0xffffffff01b08000" + ], + [ + "../firemarshal/boards/firechip/drivers/iceblk-driver/iceblk.o", + "0xffffffff01b88000" + ] ], "receivers": { - "bb_stats": { "enabled": true, "path": "trace.bb_stats.csv", "do_user": true} + "txt": { + "enabled": false, + "path": "trace.perlbench_s.txt" + }, + "bb_stats": { + "enabled": false, + "path": "trace.bb_stats.perlbench_s.csv", + "do_user": true + }, + "sqlite": { + "enabled": true, + "path": "trace.perlbench_s.sqlite.db" + } } } diff --git a/configs/spec/linux_602_gcc.json b/configs/spec/linux_602_gcc.json new file mode 100644 index 0000000..e2f54f2 --- /dev/null +++ b/configs/spec/linux_602_gcc.json @@ -0,0 +1,45 @@ +{ + "encoded_trace": "/scratch/iansseijelly/interesting_profile/spec17-intspeed-traced-wave1-602.gcc_s.out", + "user_binaries": [ + { + "binary": "../spec2017/speckle/build/overlay/intspeed/test/602.gcc_s/sgcc_base.riscv-64", + "asids": [117] + } + ], + "machine_binary": "../firemarshal/images/firechip/spec17-intspeed-test-602-602.gcc_s/spec17-intspeed-test-602-602.gcc_s-bin", + "kernel_binary": "../firemarshal/images/firechip/spec17-intspeed-test-602-602.gcc_s/spec17-intspeed-test-602-602.gcc_s-bin-dwarf", + "kernel_jump_label_patch_log": "/scratch/iansseijelly/tacit-chipyard/sims/firesim/deploy/results-workload/2026-03-20--06-42-57-spec-chores/spec-chores-run-chores/jump_label_patch_map.txt", + "driver_binary_entry_tuples": [ + [ + "../firemarshal/boards/firechip/drivers/tacit-driver/tacit.o", + "0xffffffff01b08000" + ], + [ + "../firemarshal/boards/firechip/drivers/iceblk-driver/iceblk.o", + "0xffffffff01b88000" + ] + ], + "receivers": { + "txt": { + "enabled": true, + "path": "trace.gcc_s.txt" + }, + "bb_stats": { + "enabled": false, + "path": "trace.bb_stats.gcc_s.csv", + "do_user": true + }, + "speedscope": { + "enabled": true, + "path": "trace.gcc_s.speedscope.json" + }, + "stack_txt": { + "enabled": true, + "path": "trace.gcc_s.stack.txt" + }, + "sqlite": { + "enabled": false, + "path": "trace.gcc_s.sqlite.db" + } + } +} diff --git a/configs/spec/linux_605_mcf.json b/configs/spec/linux_605_mcf.json index de8c6e6..7a84840 100644 --- a/configs/spec/linux_605_mcf.json +++ b/configs/spec/linux_605_mcf.json @@ -1,16 +1,28 @@ { "encoded_trace": "/scratch/iansseijelly/FIRESIM_RUN_TMP/sim_slot_1/tacit0.out", "user_binaries": [ - {"binary": "../spec2017/speckle/build/overlay/intspeed/test/605.mcf_s/mcf_s_base.riscv-64", "asids": [117]} + { + "binary": "../spec2017/speckle/build/overlay/intspeed/test/605.mcf_s/mcf_s_base.riscv-64", + "asids": [117] + } ], - "machine_binary": "../firemarshal/images/firechip/spec17-intspeed-test-605-605.mcf_s/spec17-intspeed-test-605-605.mcf_s-bin", - "kernel_binary": "../firemarshal/images/firechip/spec17-intspeed-test-605-605.mcf_s/spec17-intspeed-test-605-605.mcf_s-bin-dwarf", - "kernel_jump_label_patch_log": "/scratch/iansseijelly/tacit-chipyard/sims/firesim/deploy/results-workload/2025-11-15--01-13-55-spec17-intspeed-test-605/spec17-intspeed-test-605-run-chores/jump_label_patch_map.txt", + "machine_binary": "../firemarshal/images/firechip/spec17-intspeed-traced-wave1-600.perlbench_s-traced/spec17-intspeed-traced-wave1-600.perlbench_s-traced-bin", + "kernel_binary": "../firemarshal/images/firechip/spec17-intspeed-traced-wave1-600.perlbench_s-traced/spec17-intspeed-traced-wave1-600.perlbench_s-traced-bin-dwarf", + "kernel_jump_label_patch_log": "/scratch/iansseijelly/tacit-chipyard/sims/firesim/deploy/results-workload/2026-03-20--06-42-57-spec-chores/spec-chores-run-chores/jump_label_patch_map.txt", "driver_binary_entry_tuples": [ - ["../firemarshal/boards/firechip/drivers/tacit-driver/tacit.o", "0xffffffff0169d000"], - ["../firemarshal/boards/firechip/drivers/iceblk-driver/iceblk.o", "0xffffffff016ac000"] + [ + "../firemarshal/boards/firechip/drivers/tacit-driver/tacit.o", + "0xffffffff01b08000" + ], + [ + "../firemarshal/boards/firechip/drivers/iceblk-driver/iceblk.o", + "0xffffffff01b88000" + ] ], "receivers": { - "bb_stats": { "enabled": true, "path": "trace.bb_stats.csv", "do_user": true} + "sqlite": { + "enabled": true, + "path": "trace.mcf_s.sqlite.db" + } } } diff --git a/configs/spec/linux_620_omnetpp.json b/configs/spec/linux_620_omnetpp.json new file mode 100644 index 0000000..1037164 --- /dev/null +++ b/configs/spec/linux_620_omnetpp.json @@ -0,0 +1,33 @@ +{ + "encoded_trace": "/scratch/iansseijelly/interesting_profile/spec17-intspeed-traced-wave1-620.omnetpp_s.out", + "user_binaries": [ + { + "binary": "../spec2017/speckle/build/overlay/intspeed/test/620.omnetpp_s/omnetpp_s_base.riscv-64", + "asids": [117] + } + ], + "machine_binary": "../firemarshal/images/firechip/spec17-intspeed-traced-wave1-600.perlbench_s-traced/spec17-intspeed-traced-wave1-600.perlbench_s-traced-bin", + "kernel_binary": "../firemarshal/images/firechip/spec17-intspeed-traced-wave1-600.perlbench_s-traced/spec17-intspeed-traced-wave1-600.perlbench_s-traced-bin-dwarf", + "kernel_jump_label_patch_log": "/scratch/iansseijelly/tacit-chipyard/sims/firesim/deploy/results-workload/2026-03-20--06-42-57-spec-chores/spec-chores-run-chores/jump_label_patch_map.txt", + "driver_binary_entry_tuples": [ + [ + "../firemarshal/boards/firechip/drivers/tacit-driver/tacit.o", + "0xffffffff01b08000" + ], + [ + "../firemarshal/boards/firechip/drivers/iceblk-driver/iceblk.o", + "0xffffffff01b88000" + ] + ], + "receivers": { + "sqlite": { + "enabled": true, + "path": "trace.omnetpp_s.sqlite.db" + }, + "bb_stats": { + "enabled": false, + "path": "trace.bb_stats.omnetpp_s.csv", + "do_user": true + } + } +} diff --git a/configs/spec/linux_623_xalancbmk.json b/configs/spec/linux_623_xalancbmk.json new file mode 100644 index 0000000..51404b6 --- /dev/null +++ b/configs/spec/linux_623_xalancbmk.json @@ -0,0 +1,33 @@ +{ + "encoded_trace": "/scratch/iansseijelly/interesting_profile/spec17-intspeed-traced-wave1-623.xalancbmk_s.out", + "user_binaries": [ + { + "binary": "../spec2017/speckle/build/overlay/intspeed/test/623.xalancbmk_s/xalancbmk_s_base.riscv-64", + "asids": [117] + } + ], + "machine_binary": "../firemarshal/images/firechip/spec17-intspeed-traced-wave1-600.perlbench_s-traced/spec17-intspeed-traced-wave1-600.perlbench_s-traced-bin", + "kernel_binary": "../firemarshal/images/firechip/spec17-intspeed-traced-wave1-600.perlbench_s-traced/spec17-intspeed-traced-wave1-600.perlbench_s-traced-bin-dwarf", + "kernel_jump_label_patch_log": "/scratch/iansseijelly/tacit-chipyard/sims/firesim/deploy/results-workload/2026-03-20--06-42-57-spec-chores/spec-chores-run-chores/jump_label_patch_map.txt", + "driver_binary_entry_tuples": [ + [ + "../firemarshal/boards/firechip/drivers/tacit-driver/tacit.o", + "0xffffffff01b08000" + ], + [ + "../firemarshal/boards/firechip/drivers/iceblk-driver/iceblk.o", + "0xffffffff01b88000" + ] + ], + "receivers": { + "sqlite": { + "enabled": true, + "path": "trace.xalancbmk_s.sqlite.db" + }, + "bb_stats": { + "enabled": false, + "path": "trace.bb_stats.xalancbmk_s.csv", + "do_user": true + } + } +} diff --git a/configs/spec/linux_625_x264.json b/configs/spec/linux_625_x264.json index e9e2c16..fceb752 100644 --- a/configs/spec/linux_625_x264.json +++ b/configs/spec/linux_625_x264.json @@ -1,16 +1,33 @@ { - "encoded_trace": "/scratch/iansseijelly/FIRESIM_RUN_TMP/sim_slot_0/tacit0.out", + "encoded_trace": "/scratch/iansseijelly/interesting_profile/spec17-intspeed-traced-wave1-625.x264_s.out", "user_binaries": [ - {"binary": "../spec2017/speckle/build/overlay/intspeed/test/625.x264_s/x264_s_base.riscv-64", "asids": [117]} + { + "binary": "../spec2017/speckle/build/overlay/intspeed/test/625.x264_s/x264_s_base.riscv-64", + "asids": [117] + } ], - "machine_binary": "../firemarshal/images/firechip/spec17-intspeed-test-625.x264_s/spec17-intspeed-test-625.x264_s-bin", - "kernel_binary": "../firemarshal/images/firechip/spec17-intspeed-test-625.x264_s/spec17-intspeed-test-625.x264_s-bin-dwarf", - "kernel_jump_label_patch_log": "/scratch/iansseijelly/tacit-chipyard/sims/firesim/deploy/results-workload/2025-11-15--01-13-55-spec17-intspeed-test-605/spec17-intspeed-test-605-run-chores/jump_label_patch_map.txt", + "machine_binary": "../firemarshal/images/firechip/spec17-intspeed-traced-wave1-600.perlbench_s-traced/spec17-intspeed-traced-wave1-600.perlbench_s-traced-bin", + "kernel_binary": "../firemarshal/images/firechip/spec17-intspeed-traced-wave1-600.perlbench_s-traced/spec17-intspeed-traced-wave1-600.perlbench_s-traced-bin-dwarf", + "kernel_jump_label_patch_log": "/scratch/iansseijelly/tacit-chipyard/sims/firesim/deploy/results-workload/2026-03-20--06-42-57-spec-chores/spec-chores-run-chores/jump_label_patch_map.txt", "driver_binary_entry_tuples": [ - ["../firemarshal/boards/firechip/drivers/tacit-driver/tacit.o", "0xffffffff0169d000"], - ["../firemarshal/boards/firechip/drivers/iceblk-driver/iceblk.o", "0xffffffff016ac000"] + [ + "../firemarshal/boards/firechip/drivers/tacit-driver/tacit.o", + "0xffffffff01b08000" + ], + [ + "../firemarshal/boards/firechip/drivers/iceblk-driver/iceblk.o", + "0xffffffff01b88000" + ] ], "receivers": { - "bb_stats": { "enabled": true, "path": "trace.bb_stats.csv", "do_user": true} + "sqlite": { + "enabled": true, + "path": "trace.x264_s.sqlite.db" + }, + "bb_stats": { + "enabled": false, + "path": "trace.bb_stats.x264_s.csv", + "do_user": true + } } } diff --git a/configs/spec/linux_641_leela.json b/configs/spec/linux_641_leela.json index 46e534a..475ef5c 100644 --- a/configs/spec/linux_641_leela.json +++ b/configs/spec/linux_641_leela.json @@ -1,16 +1,33 @@ { - "encoded_trace": "/scratch/iansseijelly/FIRESIM_RUN_TMP/sim_slot_0/tacit0.out", + "encoded_trace": "/scratch/iansseijelly/interesting_profile/spec17-intspeed-traced-wave2-641.leela_s.out", "user_binaries": [ - ["../spec2017/speckle/build/overlay/intspeed/test/641.leela_s/leela_s_base.riscv-64", "117"] + { + "binary": "../spec2017/speckle/build/overlay/intspeed/test/641.leela_s/leela_s_base.riscv-64", + "asids": [117] + } ], - "machine_binary": "../firemarshal/images/firechip/spec17-intspeed-test-641.leela_s/spec17-intspeed-test-641.leela_s-bin", - "kernel_binary": "../firemarshal/images/firechip/spec17-intspeed-test-641.leela_s/spec17-intspeed-test-641.leela_s-bin-dwarf", - "kernel_jump_label_patch_log": "/scratch/iansseijelly/tacit-chipyard/sims/firesim/deploy/results-workload/2025-11-15--01-13-55-spec17-intspeed-test-605/spec17-intspeed-test-605-run-chores/jump_label_patch_map.txt", + "machine_binary": "../firemarshal/images/firechip/spec17-intspeed-traced-wave1-600.perlbench_s-traced/spec17-intspeed-traced-wave1-600.perlbench_s-traced-bin", + "kernel_binary": "../firemarshal/images/firechip/spec17-intspeed-traced-wave1-600.perlbench_s-traced/spec17-intspeed-traced-wave1-600.perlbench_s-traced-bin-dwarf", + "kernel_jump_label_patch_log": "/scratch/iansseijelly/tacit-chipyard/sims/firesim/deploy/results-workload/2026-03-20--06-42-57-spec-chores/spec-chores-run-chores/jump_label_patch_map.txt", "driver_binary_entry_tuples": [ - ["../firemarshal/boards/firechip/drivers/tacit-driver/tacit.o", "0xffffffff0169d000"], - ["../firemarshal/boards/firechip/drivers/iceblk-driver/iceblk.o", "0xffffffff016ac000"] + [ + "../firemarshal/boards/firechip/drivers/tacit-driver/tacit.o", + "0xffffffff01b08000" + ], + [ + "../firemarshal/boards/firechip/drivers/iceblk-driver/iceblk.o", + "0xffffffff01aa7000" + ] ], "receivers": { - "bb_stats": { "enabled": true, "path": "trace.bb_stats.csv", "do_user": true} + "sqlite": { + "enabled": true, + "path": "trace.leela_s.sqlite.db" + }, + "bb_stats": { + "enabled": false, + "path": "trace.bb_stats.leela_s.csv", + "do_user": true + } } } diff --git a/configs/spec/linux_648_exchange2.json b/configs/spec/linux_648_exchange2.json index 16f557e..f4f1d98 100644 --- a/configs/spec/linux_648_exchange2.json +++ b/configs/spec/linux_648_exchange2.json @@ -1,16 +1,33 @@ { - "encoded_trace": "/scratch/iansseijelly/FIRESIM_RUN_TMP/sim_slot_0/tacit0.out", + "encoded_trace": "/scratch/iansseijelly/interesting_profile/spec17-intspeed-traced-wave2-648.exchange2_s.out", "user_binaries": [ - {"binary": "../spec2017/speckle/build/overlay/intspeed/test/648.exchange2_s/exchange2_s_base.riscv-64", "asids": [117]} + { + "binary": "../spec2017/speckle/build/overlay/intspeed/test/648.exchange2_s/exchange2_s_base.riscv-64", + "asids": [117] + } ], - "machine_binary": "../firemarshal/images/firechip/spec17-intspeed-test-648.exchange2_s/spec17-intspeed-test-648.exchange2_s-bin", - "kernel_binary": "../firemarshal/images/firechip/spec17-intspeed-test-648.exchange2_s/spec17-intspeed-test-648.exchange2_s-bin-dwarf", - "kernel_jump_label_patch_log": "/scratch/iansseijelly/tacit-chipyard/sims/firesim/deploy/results-workload/2025-11-15--01-13-55-spec17-intspeed-test-605/spec17-intspeed-test-605-run-chores/jump_label_patch_map.txt", + "machine_binary": "../firemarshal/images/firechip/spec17-intspeed-traced-wave1-600.perlbench_s-traced/spec17-intspeed-traced-wave1-600.perlbench_s-traced-bin", + "kernel_binary": "../firemarshal/images/firechip/spec17-intspeed-traced-wave1-600.perlbench_s-traced/spec17-intspeed-traced-wave1-600.perlbench_s-traced-bin-dwarf", + "kernel_jump_label_patch_log": "/scratch/iansseijelly/tacit-chipyard/sims/firesim/deploy/results-workload/2026-03-20--06-42-57-spec-chores/spec-chores-run-chores/jump_label_patch_map.txt", "driver_binary_entry_tuples": [ - ["../firemarshal/boards/firechip/drivers/tacit-driver/tacit.o", "0xffffffff0169d000"], - ["../firemarshal/boards/firechip/drivers/iceblk-driver/iceblk.o", "0xffffffff016ac000"] + [ + "../firemarshal/boards/firechip/drivers/tacit-driver/tacit.o", + "0xffffffff01b08000" + ], + [ + "../firemarshal/boards/firechip/drivers/iceblk-driver/iceblk.o", + "0xffffffff01b88000" + ] ], "receivers": { - "bb_stats": { "enabled": true, "path": "trace.bb_stats.csv", "do_user": true} + "sqlite": { + "enabled": true, + "path": "trace.exchange2_s.sqlite.db" + }, + "bb_stats": { + "enabled": false, + "path": "trace.bb_stats.exchange2_s.csv", + "do_user": true + } } } diff --git a/configs/spec/linux_657_xz_cld.json b/configs/spec/linux_657_xz_cld.json new file mode 100644 index 0000000..c8ea34c --- /dev/null +++ b/configs/spec/linux_657_xz_cld.json @@ -0,0 +1,33 @@ +{ + "encoded_trace": "/scratch/iansseijelly/interesting_profile/spec17-intspeed-traced-wave2-657.xz_s-cld.out", + "user_binaries": [ + { + "binary": "../spec2017/speckle/build/overlay/intspeed/test/657.xz_s/xz_s_base.riscv-64", + "asids": [117] + } + ], + "machine_binary": "../firemarshal/images/firechip/spec17-intspeed-traced-wave1-600.perlbench_s-traced/spec17-intspeed-traced-wave1-600.perlbench_s-traced-bin", + "kernel_binary": "../firemarshal/images/firechip/spec17-intspeed-traced-wave1-600.perlbench_s-traced/spec17-intspeed-traced-wave1-600.perlbench_s-traced-bin-dwarf", + "kernel_jump_label_patch_log": "/scratch/iansseijelly/tacit-chipyard/sims/firesim/deploy/results-workload/2026-03-20--06-42-57-spec-chores/spec-chores-run-chores/jump_label_patch_map.txt", + "driver_binary_entry_tuples": [ + [ + "../firemarshal/boards/firechip/drivers/tacit-driver/tacit.o", + "0xffffffff01b08000" + ], + [ + "../firemarshal/boards/firechip/drivers/iceblk-driver/iceblk.o", + "0xffffffff01b88000" + ] + ], + "receivers": { + "sqlite": { + "enabled": true, + "path": "trace.xz_s-cld.sqlite.db" + }, + "bb_stats": { + "enabled": false, + "path": "trace.bb_stats.xz_s-cld.csv", + "do_user": true + } + } +} diff --git a/configs/spec/linux_657_xz_cpu2006docs.json b/configs/spec/linux_657_xz_cpu2006docs.json new file mode 100644 index 0000000..a15f46f --- /dev/null +++ b/configs/spec/linux_657_xz_cpu2006docs.json @@ -0,0 +1,33 @@ +{ + "encoded_trace": "/scratch/iansseijelly/interesting_profile/spec17-intspeed-traced-wave2-657.xz_s-cpu2006docs.out", + "user_binaries": [ + { + "binary": "../spec2017/speckle/build/overlay/intspeed/test/657.xz_s/xz_s_base.riscv-64", + "asids": [117] + } + ], + "machine_binary": "../firemarshal/images/firechip/spec17-intspeed-traced-wave1-600.perlbench_s-traced/spec17-intspeed-traced-wave1-600.perlbench_s-traced-bin", + "kernel_binary": "../firemarshal/images/firechip/spec17-intspeed-traced-wave1-600.perlbench_s-traced/spec17-intspeed-traced-wave1-600.perlbench_s-traced-bin-dwarf", + "kernel_jump_label_patch_log": "/scratch/iansseijelly/tacit-chipyard/sims/firesim/deploy/results-workload/2026-03-20--06-42-57-spec-chores/spec-chores-run-chores/jump_label_patch_map.txt", + "driver_binary_entry_tuples": [ + [ + "../firemarshal/boards/firechip/drivers/tacit-driver/tacit.o", + "0xffffffff01b08000" + ], + [ + "../firemarshal/boards/firechip/drivers/iceblk-driver/iceblk.o", + "0xffffffff01b88000" + ] + ], + "receivers": { + "sqlite": { + "enabled": true, + "path": "trace.xz_s-cpu2006docs.sqlite.db" + }, + "bb_stats": { + "enabled": false, + "path": "trace.bb_stats.xz_s-cpu2006docs.csv", + "do_user": true + } + } +} diff --git a/crates/trace_db_tools/Cargo.toml b/crates/trace_db_tools/Cargo.toml new file mode 100644 index 0000000..536424d --- /dev/null +++ b/crates/trace_db_tools/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "trace_db_tools" +version = "0.1.0" +edition = "2021" + +[dependencies] +rusqlite = { version = "0.31", features = ["bundled"] } +clap = { version = "4.5.32", features = ["derive"] } +indicatif = "0.18.0" +anyhow = "1.0" diff --git a/crates/trace_db_tools/src/bb_stats.rs b/crates/trace_db_tools/src/bb_stats.rs new file mode 100644 index 0000000..6b32c10 --- /dev/null +++ b/crates/trace_db_tools/src/bb_stats.rs @@ -0,0 +1,185 @@ +use std::collections::HashMap; +use std::fs::{self, File}; +use std::io::Write; +use std::path::Path; + +use anyhow::{Context, Result}; +use indicatif::{ProgressBar, ProgressStyle}; +use rusqlite::Connection; + +/// Per-BB aggregation: (count, sum_delta, min_delta) +struct BbAgg { + count: u64, + sum: u64, + min: u64, +} + +/// Flattened result row: (count, mean, netvar, total, bb_start, bb_end) +type BbRow = (u64, f64, u64, u64, u64, u64); + +fn write_csv(path: &Path, rows: &[BbRow]) -> Result<()> { + let mut f = File::create(path) + .with_context(|| format!("Failed to create: {}", path.display()))?; + writeln!(f, "count,mean,netvar,total,bb")?; + for &(count, mean, netvar, total, bb_start, bb_end) in rows { + writeln!(f, "{count},{mean:.1},{netvar},{total},{bb_start:#x}-{bb_end:#x}")?; + } + Ok(()) +} + +pub fn run(db_path: &str, outdir: &str, prv: Option, ctx: Option, limit: Option) -> Result<()> { + fs::create_dir_all(outdir) + .with_context(|| format!("Failed to create output directory: {outdir}"))?; + let outdir = Path::new(outdir); + + let conn = Connection::open(db_path) + .with_context(|| format!("Failed to open database: {db_path}"))?; + + let sql_where = "event_type NOT IN ('SYNC_START', 'SYNC_END')"; + + // Get total row count for progress bar + let total_rows: u64 = conn + .query_row(&format!("SELECT COUNT(*) FROM events WHERE {sql_where}"), [], |r| r.get(0))?; + + let pb = ProgressBar::new(total_rows); + pb.set_style( + ProgressStyle::default_bar() + .template("[{elapsed_precise}] [{bar:40}] {pos}/{len} ({per_sec}, ETA {eta})")? + .progress_chars("=> "), + ); + + let query = format!( + "SELECT timestamp, from_addr, to_addr, prv, ctx FROM events WHERE {sql_where} ORDER BY id" + ); + let mut stmt = conn.prepare(&query)?; + + let mut bb_agg: HashMap<(u64, u64), BbAgg> = HashMap::new(); + let mut prev_ts: Option = None; + let mut prev_to: u64 = 0; + let mut prev_matches = false; + let mut row_idx: u64 = 0; + let pb_step = (total_rows / 100).max(1); + + let mut rows = stmt.query([])?; + while let Some(row) = rows.next()? { + let timestamp: i64 = row.get(0)?; + let from_addr = row.get::<_, i64>(1)? as u64; + let to_addr = row.get::<_, i64>(2)? as u64; + let row_prv: i64 = row.get(3)?; + let row_ctx: i64 = row.get(4)?; + + let curr_matches = + prv.map_or(true, |p| row_prv == p) && ctx.map_or(true, |c| row_ctx == c); + + if let Some(pt) = prev_ts { + if prev_matches && curr_matches { + let delta = (timestamp - pt) as u64; + let key = (prev_to, from_addr); + let agg = bb_agg.entry(key).or_insert(BbAgg { + count: 0, + sum: 0, + min: u64::MAX, + }); + agg.count += 1; + agg.sum += delta; + if delta < agg.min { + agg.min = delta; + } + } + } + + prev_ts = Some(timestamp); + prev_to = to_addr; + prev_matches = curr_matches; + + row_idx += 1; + if row_idx % pb_step == 0 { + pb.set_position(row_idx); + } + } + pb.finish_and_clear(); + + // Build full results: (count, mean, netvar, total, bb_start, bb_end) + let mut results: Vec = bb_agg + .iter() + .map(|(&(bb_start, bb_end), agg)| { + let mean = agg.sum as f64 / agg.count as f64; + let netvar = agg.sum - agg.min * agg.count; + (agg.count, mean, netvar, agg.sum, bb_start, bb_end) + }) + .collect(); + + // Summary stats (computed from all BBs, before limit) + let total_cycles: u64 = results.iter().map(|r| r.3).sum(); + let total_netvar: u64 = results.iter().map(|r| r.2).sum(); + let total_events: u64 = results.iter().map(|r| r.0).sum(); + let unique_bbs = results.len(); + + // 1. Top by netvar + results.sort_by(|a, b| b.2.cmp(&a.2)); + let top_by_netvar: Vec = results.iter().copied().take(limit.unwrap_or(results.len())).collect(); + let netvar_path = outdir.join("top_by_netvar.csv"); + write_csv(&netvar_path, &top_by_netvar)?; + eprintln!("Written {} rows to {}", top_by_netvar.len(), netvar_path.display()); + + // 2. Top by total time + results.sort_by(|a, b| b.3.cmp(&a.3)); + let top_by_total: Vec = results.iter().copied().take(limit.unwrap_or(results.len())).collect(); + let total_path = outdir.join("top_by_total.csv"); + write_csv(&total_path, &top_by_total)?; + eprintln!("Written {} rows to {}", top_by_total.len(), total_path.display()); + + // 3. Summary txt + let summary_path = outdir.join("summary.txt"); + let mut sf = File::create(&summary_path) + .with_context(|| format!("Failed to create: {}", summary_path.display()))?; + + writeln!(sf, "{}", "=".repeat(60))?; + writeln!(sf, "BB Stats Summary")?; + writeln!(sf, "{}", "=".repeat(60))?; + writeln!(sf, " Database: {db_path}")?; + writeln!(sf, " Filters: prv={} ctx={}", + prv.map_or("any".to_string(), |v| v.to_string()), + ctx.map_or("any".to_string(), |v| v.to_string()), + )?; + writeln!(sf, " Events scanned: {total_rows}")?; + writeln!(sf, " Unique BBs: {unique_bbs}")?; + writeln!(sf, " Matched events: {total_events}")?; + writeln!(sf, " Total cycles: {total_cycles}")?; + writeln!(sf, " Total netvar: {total_netvar}")?; + if let Some(top) = top_by_netvar.first() { + writeln!(sf, + " Top BB by netvar: {:#x}-{:#x} (netvar={}, count={}, mean={:.1})", + top.4, top.5, top.2, top.0, top.1 + )?; + let top10_netvar: u64 = top_by_netvar.iter().take(10).map(|r| r.2).sum(); + if total_netvar > 0 { + writeln!(sf, + " Top 10 netvar: {top10_netvar} ({:.1}% of total netvar, {:.1}% of total cycles)", + top10_netvar as f64 / total_netvar as f64 * 100.0, + top10_netvar as f64 / total_cycles as f64 * 100.0 + )?; + } + } + if let Some(top) = top_by_total.first() { + writeln!(sf, + " Top BB by total: {:#x}-{:#x} (total={}, count={}, mean={:.1})", + top.4, top.5, top.3, top.0, top.1 + )?; + let top10_total: u64 = top_by_total.iter().take(10).map(|r| r.3).sum(); + if total_cycles > 0 { + writeln!(sf, + " Top 10 total: {top10_total} ({:.1}% of total)", + top10_total as f64 / total_cycles as f64 * 100.0 + )?; + } + } + writeln!(sf, "{}", "=".repeat(60))?; + + // Also print summary to stderr + let summary = std::fs::read_to_string(&summary_path)?; + eprint!("{summary}"); + eprintln!("Written summary to {}", summary_path.display()); + + Ok(()) +} diff --git a/crates/trace_db_tools/src/check.rs b/crates/trace_db_tools/src/check.rs new file mode 100644 index 0000000..0ce614c --- /dev/null +++ b/crates/trace_db_tools/src/check.rs @@ -0,0 +1,121 @@ +use std::collections::HashMap; + +use anyhow::{Context, Result}; +use rusqlite::Connection; + +pub fn run(db_path: &str) -> Result<()> { + let conn = Connection::open(db_path) + .with_context(|| format!("Failed to open database: {db_path}"))?; + + let total_rows: u64 = conn + .query_row("SELECT COUNT(*) FROM events", [], |r| r.get(0))?; + eprintln!("Total events: {total_rows}"); + + let mut errors = 0u64; + + // 1. Check for duplicate SYNC_START (sign of appended data from re-runs) + { + let mut stmt = conn.prepare( + "SELECT id, timestamp, from_addr, ctx FROM events WHERE event_type = 'SYNC_START' ORDER BY id" + )?; + let sync_starts: Vec<(i64, i64, i64, i64)> = stmt + .query_map([], |row| { + Ok((row.get(0)?, row.get(1)?, row.get(2)?, row.get(3)?)) + })? + .collect::, _>>()?; + + eprintln!("\n[check] SYNC_START events: {}", sync_starts.len()); + if sync_starts.len() > 1 { + // Look for duplicates (same timestamp + from_addr + ctx) + let mut seen: HashMap<(i64, i64, i64), Vec> = HashMap::new(); + for &(id, ts, addr, ctx) in &sync_starts { + seen.entry((ts, addr, ctx)).or_default().push(id); + } + for ((ts, addr, ctx), ids) in &seen { + if ids.len() > 1 { + eprintln!( + " ERROR: duplicate SYNC_START (timestamp={ts}, pc={:#x}, ctx={ctx}) at ids: {ids:?}", + *addr as u64 + ); + eprintln!(" -> likely caused by appending to an existing DB without clearing it first"); + errors += 1; + } + } + } + for &(id, ts, addr, ctx) in &sync_starts { + eprintln!(" id={id} timestamp={ts} pc={:#x} ctx={ctx}", addr as u64); + } + } + + // 2. Check for non-monotonic timestamps within the same context + { + let mut stmt = conn.prepare( + "SELECT id, timestamp, ctx FROM events \ + WHERE event_type NOT IN ('SYNC_START', 'SYNC_END') \ + ORDER BY id" + )?; + let mut rows = stmt.query([])?; + + // Track prev timestamp per context + let mut prev_ts_by_ctx: HashMap = HashMap::new(); // ctx -> (prev_id, prev_ts) + let mut non_mono_count = 0u64; + let mut non_mono_examples: Vec = Vec::new(); + + while let Some(row) = rows.next()? { + let id: i64 = row.get(0)?; + let ts: i64 = row.get(1)?; + let ctx: i64 = row.get(2)?; + + if let Some(&(prev_id, prev_ts)) = prev_ts_by_ctx.get(&ctx) { + if ts < prev_ts { + non_mono_count += 1; + if non_mono_examples.len() < 5 { + non_mono_examples.push(format!( + "ctx={ctx}: id {prev_id} (ts={prev_ts}) -> id {id} (ts={ts}), delta={}", + ts - prev_ts + )); + } + } + } + prev_ts_by_ctx.insert(ctx, (id, ts)); + } + + eprintln!("\n[check] Non-monotonic timestamps (per context): {non_mono_count}"); + if non_mono_count > 0 { + errors += non_mono_count; + for ex in &non_mono_examples { + eprintln!(" ERROR: {ex}"); + } + if non_mono_count > non_mono_examples.len() as u64 { + eprintln!(" ... and {} more", non_mono_count - non_mono_examples.len() as u64); + } + } + } + + // 3. Summary of contexts + { + let mut stmt = conn.prepare( + "SELECT ctx, COUNT(*) FROM events \ + WHERE event_type NOT IN ('SYNC_START', 'SYNC_END') \ + GROUP BY ctx ORDER BY COUNT(*) DESC" + )?; + let ctx_counts: Vec<(i64, u64)> = stmt + .query_map([], |row| Ok((row.get(0)?, row.get(1)?)))? + .collect::, _>>()?; + + eprintln!("\n[check] Contexts ({} total):", ctx_counts.len()); + for &(ctx, count) in &ctx_counts { + eprintln!(" ctx={ctx}: {count} events"); + } + } + + // Final verdict + eprintln!(); + if errors == 0 { + eprintln!("OK: no issues found in {db_path}"); + } else { + eprintln!("FAIL: {errors} issue(s) found in {db_path}"); + } + + Ok(()) +} diff --git a/crates/trace_db_tools/src/main.rs b/crates/trace_db_tools/src/main.rs new file mode 100644 index 0000000..a62e6fd --- /dev/null +++ b/crates/trace_db_tools/src/main.rs @@ -0,0 +1,54 @@ +mod bb_stats; +mod check; + +use anyhow::Result; +use clap::{Parser, Subcommand}; + +#[derive(Parser)] +#[command(name = "trace_db_tools", about = "Tools for analysing SQLite trace DBs")] +struct Cli { + #[command(subcommand)] + command: Commands, +} + +#[derive(Subcommand)] +enum Commands { + /// Compute basic-block latency statistics from a trace DB + BbStats { + /// Path to SQLite trace DB + #[arg(long, default_value = "trace.db")] + db: String, + /// Output directory for CSVs and summary + #[arg(long, default_value = "bb_stats_out")] + outdir: String, + /// Filter by privilege level (0=user, 1=supervisor, 3=machine) + #[arg(long)] + prv: Option, + /// Filter by ASID context + #[arg(long)] + ctx: Option, + /// Limit number of output rows per CSV + #[arg(long)] + limit: Option, + }, + /// Sanity-check a trace DB for common issues + Check { + /// Path to SQLite trace DB + #[arg(long, default_value = "trace.db")] + db: String, + }, +} + +fn main() -> Result<()> { + let cli = Cli::parse(); + match cli.command { + Commands::BbStats { + db, + outdir, + prv, + ctx, + limit, + } => bb_stats::run(&db, &outdir, prv, ctx, limit), + Commands::Check { db } => check::run(&db), + } +} diff --git a/scripts/analysis/plot_bb_stats.py b/scripts/analysis/plot_bb_stats.py new file mode 100644 index 0000000..f0f5a6a --- /dev/null +++ b/scripts/analysis/plot_bb_stats.py @@ -0,0 +1,231 @@ +import matplotlib +import matplotlib.pyplot as plt +plt.style.use('seaborn-v0_8-colorblind') +plt.rc('font', family='serif') +plt.rc('font', serif='Latin Modern Roman') +matplotlib.rcParams.update({'font.size': 18}) +import pandas as pd +import numpy as np +import os +import sys +import argparse + +BENCHMARKS = [ + "perlbench", "gcc", "mcf", "omnetpp", "xalancbmk", "x264", + "leela", "exchange2", "xz-cpu2006docs", "xz-cld", +] + + +def load_data(base_dir): + """Load top_by_netvar.csv, top_by_total.csv, and summary.txt for each benchmark.""" + data = {} + for name in BENCHMARKS: + bdir = os.path.join(base_dir, name) + if not os.path.isdir(bdir): + print(f"WARNING: skipping {name}, directory not found", file=sys.stderr) + continue + netvar_df = pd.read_csv(os.path.join(bdir, "top_by_netvar.csv")) + total_df = pd.read_csv(os.path.join(bdir, "top_by_total.csv")) + + # Parse total_cycles from summary.txt + total_cycles = None + total_netvar = None + with open(os.path.join(bdir, "summary.txt")) as f: + for line in f: + if "Total cycles:" in line: + total_cycles = int(line.strip().split()[-1]) + if "Total netvar:" in line: + total_netvar = int(line.strip().split()[-1]) + + data[name] = { + "netvar": netvar_df, + "total": total_df, + "total_cycles": total_cycles, + "total_netvar": total_netvar, + } + print(f"--------------------------------") + print(f"Loaded {name} with total_cycles={total_cycles}", file=sys.stderr) + return data + + +def plot_top_netvar_tc_stacked(data, outpath): + """Stacked bar chart: top 10 netvar BBs as % of total cycles per benchmark.""" + fig, ax = plt.subplots(figsize=(14, 6)) + + names = list(data.keys()) + n = len(names) + x = range(n) + + # For each benchmark, compute per-BB percentage of total cycles + # Stack from bottom (rank 1) to top (rank 10) + max_rank = 10 + bottoms = [0.0] * n + colors = plt.cm.rainbow(np.linspace(0, 1, 10)) + + for rank in range(max_rank): + heights = [] + for name in names: + d = data[name] + df = d["netvar"] + tc = d["total_cycles"] + if rank < len(df) and tc and tc > 0: + pct = df.iloc[rank]["netvar"] / tc * 100 + # print(f"Rank {rank+1} of {name} has {pct}% of total netvar", file=sys.stderr) + else: + pct = 0.0 + heights.append(pct) + ax.bar(x, heights, bottom=bottoms, color=colors[rank], + label=f"Rank {rank+1}", edgecolor="white", linewidth=0.3) + bottoms = [b + h for b, h in zip(bottoms, heights)] + + # Add "rest" bar to show what fraction is NOT in top 10 + rest = [] + for i, name in enumerate(names): + rest.append(100.0 - bottoms[i]) + ax.bar(x, rest, bottom=bottoms, color="#e0e0e0", label="Other BBs", + edgecolor="white", linewidth=0.3) + for i in range(n): + ax.text(i, bottoms[i] + rest[i] / 2, f"{rest[i]:.0f}%", ha="center", va="center", color="#555555") + + ax.set_xticks(x) + ax.set_xticklabels(names, rotation=35, ha="right") + ax.set_ylabel("% of Total Cycles") + ax.set_title("Top 10 BBs by Netvar: Share of Total Cycles") + # ax.legend(bbox_to_anchor=(1.02, 1), loc="upper left") + ax.set_ylim(0, 100) + fig.tight_layout() + fig.savefig(outpath, dpi=150) + plt.close(fig) + print(f"Saved {outpath}", file=sys.stderr) + +def plot_top_netvar_tn_stacked(data, outpath): + """Stacked bar chart: top 10 netvar BBs as % of total cycles per benchmark.""" + fig, ax = plt.subplots(figsize=(14, 6)) + + names = list(data.keys()) + n = len(names) + x = range(n) + + # For each benchmark, compute per-BB percentage of total cycles + # Stack from bottom (rank 1) to top (rank 10) + max_rank = 10 + bottoms = [0.0] * n + colors = plt.cm.rainbow(np.linspace(0, 1, 10)) + + for rank in range(max_rank): + heights = [] + for name in names: + d = data[name] + df = d["netvar"] + tn = d["total_netvar"] + if rank < len(df) and tn and tn > 0: + pct = df.iloc[rank]["netvar"] / tn * 100 + # print(f"Rank {rank+1} of {name} has {pct}% of total netvar", file=sys.stderr) + else: + pct = 0.0 + heights.append(pct) + ax.bar(x, heights, bottom=bottoms, color=colors[rank], + label=f"Rank {rank+1}", edgecolor="white", linewidth=0.3) + bottoms = [b + h for b, h in zip(bottoms, heights)] + + # Add "rest" bar to show what fraction is NOT in top 10 + rest = [] + for i, name in enumerate(names): + rest.append(100.0 - bottoms[i]) + ax.bar(x, rest, bottom=bottoms, color="#e0e0e0", label="Other BBs", + edgecolor="white", linewidth=0.3) + for i in range(n): + ax.text(i, bottoms[i] + rest[i] / 2, f"{rest[i]:.0f}%", ha="center", va="center", color="#555555") + + ax.set_xticks(x) + ax.set_xticklabels(names, rotation=35, ha="right") + ax.set_ylabel("% of Total Netvar") + ax.set_title("Top 10 BBs by Netvar: Share of Total Netvar") + # ax.legend(bbox_to_anchor=(1.02, 1), loc="upper left") + ax.set_ylim(0, 100) + fig.tight_layout() + fig.savefig(outpath, dpi=150) + plt.close(fig) + print(f"Saved {outpath}", file=sys.stderr) + + +def plot_rank_comparison(data, outpath): + """Bump chart per benchmark: netvar rank (left) vs total rank (right) with connecting lines.""" + names = list(data.keys()) + n = len(names) + cols = 5 + rows = (n + cols - 1) // cols + fig, axes = plt.subplots(rows, cols, figsize=(4 * cols, 4 * rows)) + axes = axes.flatten() + + colors = plt.cm.rainbow(np.linspace(0, 1, 10)) + + for idx, name in enumerate(names): + ax = axes[idx] + netvar_df = data[name]["netvar"] + total_df = data[name]["total"] + + # Build rank maps: bb -> rank (1-indexed) + netvar_rank = {bb: i + 1 for i, bb in enumerate(netvar_df["bb"])} + total_rank = {bb: i + 1 for i, bb in enumerate(total_df["bb"])} + all_bbs = list(dict.fromkeys(list(netvar_df["bb"]) + list(total_df["bb"]))) + + max_rank = max(len(netvar_df), len(total_df)) + unranked = max_rank + 1.5 # position for BBs not in a list + + for i, bb in enumerate(all_bbs): + nr = netvar_rank.get(bb) + tr = total_rank.get(bb) + left = nr if nr else unranked + right = tr if tr else unranked + + if nr and tr: + # In both lists — solid colored line + c = colors[(nr - 1) % 10] + ax.plot([0, 1], [left, right], color=c, linewidth=1.5, alpha=0.8, + solid_capstyle="round") + ax.plot(0, left, "o", color=c, markersize=5) + ax.plot(1, right, "o", color=c, markersize=5) + elif nr: + # Netvar only — dashed to unranked + ax.plot([0, 1], [left, right], color="#dd8452", linewidth=1, + linestyle="--", alpha=0.5) + ax.plot(0, left, "o", color="#dd8452", markersize=4) + else: + # Total only — dashed from unranked + ax.plot([0, 1], [left, right], color="#55a868", linewidth=1, + linestyle="--", alpha=0.5) + ax.plot(1, right, "o", color="#55a868", markersize=4) + + ax.set_xlim(-0.3, 1.3) + ax.set_ylim(unranked + 0.5, 0.5) + ax.set_xticks([0, 1]) + ax.set_xticklabels(["Netvar", "Total"]) + ax.set_yticks(range(1, max_rank + 1)) + ax.set_ylabel("Rank") + ax.set_title(name, fontweight="bold") + ax.axhline(y=max_rank + 0.75, color="gray", linewidth=0.5, linestyle=":") + + # Hide unused subplots + for idx in range(n, len(axes)): + axes[idx].set_visible(False) + + fig.suptitle("Rank Comparison: Netvar vs Total Time (top 10)", y=1.01) + fig.tight_layout() + fig.savefig(outpath, dpi=150, bbox_inches="tight") + plt.close(fig) + print(f"Saved {outpath}", file=sys.stderr) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Plot BB stats across benchmarks") + parser.add_argument("--indir", required=True, help="Base directory with per-benchmark subdirs") + parser.add_argument("--outdir", default=".", help="Directory for output PNGs") + args = parser.parse_args() + + os.makedirs(args.outdir, exist_ok=True) + data = load_data(args.indir) + + plot_top_netvar_tc_stacked(data, os.path.join(args.outdir, "top_netvar_tc_share.png")) + plot_top_netvar_tn_stacked(data, os.path.join(args.outdir, "top_netvar_tn_share.png")) + plot_rank_comparison(data, os.path.join(args.outdir, "netvar_vs_total_rank.png")) diff --git a/scripts/analysis/plot_emulation_errors.py b/scripts/analysis/plot_emulation_errors.py new file mode 100644 index 0000000..0c60266 --- /dev/null +++ b/scripts/analysis/plot_emulation_errors.py @@ -0,0 +1,196 @@ +import matplotlib +import matplotlib.pyplot as plt +import numpy as np +import argparse +import os +import re + +matplotlib.rcParams.update({'font.size': 18}) + +BENCHMARKS = [ + "600_perlbench", + "602_gcc", + "605_mcf", + "620_omnetpp", + "623_xalancbmk", + "625_x264", + "641_leela", + "648_exchange2", + "657_xz_cld", + "657_xz_cpu2006docs", +] + +# Pattern: BB Emulation Error (name): Weighted Error XX.XXXX% +# Pattern: Func Emulation Error (name): Weighted Error XX.XXXX% +BB_PATTERN = re.compile(r'BB Emulation Error \((.+?)\): Weighted Error ([\d.]+)%') +FUNC_PATTERN = re.compile(r'Func Emulation Error \((.+?)\): Weighted Error ([\d.]+)%') + + +def parse_results(trace_errors_dir: str): + bb_results = {} # emulator_name -> {benchmark -> error} + func_results = {} + + for bench in BENCHMARKS: + path = os.path.join(trace_errors_dir, f"{bench}.txt") + if not os.path.exists(path): + print(f"Warning: {path} not found, skipping") + continue + with open(path) as f: + content = f.read() + + for m in BB_PATTERN.finditer(content): + name, error = m.group(1), float(m.group(2)) + bb_results.setdefault(name, {})[bench] = error + + for m in FUNC_PATTERN.finditer(content): + name, error = m.group(1), float(m.group(2)) + func_results.setdefault(name, {})[bench] = error + + return bb_results, func_results + + +def plot_grouped_bar(results: dict, title: str, output_path: str, legend_loc: str = 'lower right'): + if not results: + print(f"No data for {title}, skipping") + return + + emulators = sorted(results.keys()) + benchmarks = [b for b in BENCHMARKS if any(b in results[e] for e in emulators)] + short_names = [b.split('_', 1)[1] for b in benchmarks] + + x = np.arange(len(benchmarks)) + n = len(emulators) + width = 0.8 / n + + def legend_name(emu_name): + if 'tnt_cyc_nret' in emu_name: + return 'TNT_CYC_NRET' + if 'tnt_cyc_retcompressed' in emu_name: + return 'TNT_CYC' + if emu_name.startswith('tc_'): + return 'TC' + return emu_name + + fig, ax = plt.subplots(figsize=(10, 7)) + for i, emu in enumerate(emulators): + values = [results[emu].get(b, 0) for b in benchmarks] + offset = (i - n / 2 + 0.5) * width + ax.bar(x + offset, values, width, label=legend_name(emu)) + + ax.set_xlabel('Benchmark') + ax.set_ylabel('Weighted Error (%)') + ax.set_title(title, pad=15) + ax.set_xticks(x) + ax.set_xticklabels(short_names, rotation=45, ha='right') + + ax.legend(loc=legend_loc, fontsize=16) + ax.grid(axis='y', linestyle=':', alpha=0.5) + plt.tight_layout() + plt.savefig(output_path, dpi=300) + plt.close() + print(f"Saved {output_path}") + + +def print_summary(bb_results, func_results): + print('=' * 80) + print('BB Emulation Errors (Weighted Error %)') + print('=' * 80) + emulators = sorted(bb_results.keys()) + header = f"{'Benchmark':25s}" + "".join(f"{e:>20s}" for e in emulators) + print(header) + for bench in BENCHMARKS: + row = f"{bench:25s}" + for emu in emulators: + val = bb_results.get(emu, {}).get(bench, None) + row += f"{val:>19.4f}%" if val is not None else f"{'N/A':>20s}" + print(row) + + print() + print('=' * 80) + print('Func Emulation Errors (Weighted Error %)') + print('=' * 80) + emulators = sorted(func_results.keys()) + header = f"{'Benchmark':25s}" + "".join(f"{e:>20s}" for e in emulators) + print(header) + for bench in BENCHMARKS: + row = f"{bench:25s}" + for emu in emulators: + val = func_results.get(emu, {}).get(bench, None) + row += f"{val:>19.4f}%" if val is not None else f"{'N/A':>20s}" + print(row) + print('=' * 80) + + +def legend_name(emu_name): + if 'tnt_cyc_nret' in emu_name: + return 'TNT_CYC_NRET' + if 'tnt_cyc_retcompressed' in emu_name: + return 'TNT_CYC' + if emu_name.startswith('tc_'): + return 'TC' + return emu_name + + +def plot_combined(bb_results: dict, func_results: dict, output_path: str): + if not bb_results or not func_results: + print("Missing data for combined plot, skipping") + return + + # Group by emulation strategy — match BB and Func keys by legend name + bb_keys = sorted(bb_results.keys()) + func_keys = sorted(func_results.keys()) + strategies = [] # (legend_label, bb_key, func_key) + seen = set() + for key in bb_keys: + label = legend_name(key) + if label in seen: + continue + seen.add(label) + func_key = next((k for k in func_keys if legend_name(k) == label), None) + strategies.append((label, key, func_key)) + + benchmarks = [b for b in BENCHMARKS if any(b in bb_results.get(s[1], {}) for s in strategies)] + short_names = [b.split('_', 1)[1] for b in benchmarks] + + x = np.arange(len(benchmarks)) + n = len(strategies) + colors = [plt.cm.tab10(i) for i in range(n)] + width = 0.8 / n + + fig, (ax_bb, ax_func) = plt.subplots(2, 1, figsize=(10, 9), sharex=True) + + for i, (label, bb_key, func_key) in enumerate(strategies): + offset = -0.4 + width * (i + 0.5) + bb_vals = [bb_results.get(bb_key, {}).get(b, 0) for b in benchmarks] + ax_bb.bar(x + offset, bb_vals, width * 0.95, color=colors[i], label=label) + if func_key: + func_vals = [func_results.get(func_key, {}).get(b, 0) for b in benchmarks] + ax_func.bar(x + offset, func_vals, width * 0.95, color=colors[i]) + + ax_bb.set_ylabel('Weighted Error (%)') + ax_bb.set_title('BB-Level', pad=10) + ax_bb.grid(axis='y', linestyle=':', alpha=0.5) + + ax_func.set_ylabel('Weighted Error (%)') + ax_func.set_title('Func-Level', pad=10) + ax_func.set_xticks(x) + ax_func.set_xticklabels(short_names, rotation=45, ha='right') + ax_func.grid(axis='y', linestyle=':', alpha=0.5) + + fig.legend(*ax_bb.get_legend_handles_labels(), loc='upper center', ncol=n, fontsize=16, bbox_to_anchor=(0.5, 1.02)) + fig.suptitle('Emulation Weighted Error by Benchmark', fontsize=18, y=1.08) + plt.tight_layout() + plt.savefig(output_path, dpi=300, bbox_inches='tight') + plt.close() + print(f"Saved {output_path}") + + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description='Plot emulation error results') + parser.add_argument('--dir', type=str, default='trace_errors', help='Directory with benchmark .txt outputs') + parser.add_argument('--output-prefix', type=str, default='emulation_error', help='Output file prefix') + args = parser.parse_args() + + bb_results, func_results = parse_results(args.dir) + print_summary(bb_results, func_results) + plot_combined(bb_results, func_results, f'{args.output_prefix}.combined.png') diff --git a/scripts/analysis/plot_func_path_pareto.py b/scripts/analysis/plot_func_path_pareto.py new file mode 100644 index 0000000..27a176f --- /dev/null +++ b/scripts/analysis/plot_func_path_pareto.py @@ -0,0 +1,128 @@ +import pandas as pd +import matplotlib.pyplot as plt +import matplotlib.ticker as mticker +import matplotlib +import sys + +matplotlib.rcParams.update({'font.size': 16}) + +named_bbs = { + "0x80000418": "trap save", + "0x8000290c": "memcpy", + "0x800053cc": "atmoic exchange", + "0x800054fa": "spin_lock", + "0x800004a6": "trap restore", + "0x800022c4": "pmu_ctr_incr_fw", + "0x800010b2": "ipi process", + "0x80005526": "spin_unlock", + "0x80008756": "hart_has_extension", + "0x80003a74": "trap_handler", + "0x80002908": "memcpy", + "0x80017c98": "clear clint ipi" +} + +def main(): + if len(sys.argv) < 2: + print("Usage: python plot_func_path_pareto.py [output_png]") + sys.exit(1) + + bb_csv = sys.argv[1] + output = sys.argv[2] if len(sys.argv) > 2 else "func_path_pareto.png" + + df = pd.read_csv(bb_csv) + # strip whitespace from column names + df.columns = df.columns.str.strip() + + # aggregate by BB + bb_agg = df.groupby(["bb_start", "bb_end"]).agg( + total_cycles=("duration", "sum"), + count=("duration", "count"), + mean_cycles=("duration", "mean"), + ).reset_index() + + bb_agg = bb_agg.sort_values("total_cycles", ascending=False).reset_index(drop=True) + + top_n = 12 + top = bb_agg.head(top_n).copy() + other_total = bb_agg.iloc[top_n:]["total_cycles"].sum() + + # labels + top["label"] = top.apply( + lambda r: f"{r['bb_start']}", axis=1 + ) + # substitute named bbs + top["label"] = top["label"].apply( + lambda k: named_bbs[k] if k in named_bbs else k + ) + labels = list(top["label"]) + ["Other"] + values = list(top["total_cycles"]) + [other_total] + + grand_total = sum(values) + cumulative = [] + running = 0 + for v in values: + running += v + cumulative.append(running / grand_total * 100) + + top_pct = cumulative[top_n - 1] + + # convert to % of total + values_pct = [v / grand_total * 100 for v in values] + + # plot + fig, ax1 = plt.subplots(figsize=(10,6)) + + bars = ax1.bar(range(len(labels)), values_pct, color="#4878CF", edgecolor="white", zorder=2) + # highlight "Other" bar + bars[-1].set_color("#CCCCCC") + + ax1.set_ylabel("% of Total Cycles") + ax1.set_xticks(range(len(labels))) + ax1.set_xticklabels(labels, rotation=45, ha="right", fontsize=12, family="monospace") + ax1.set_xlim(-0.6, len(labels) - 0.4) + ax1.grid(axis="y", alpha=0.3, zorder=0) + + # cumulative line on secondary axis + ax2 = ax1.twinx() + ax2.plot(range(len(labels)), cumulative, color="#D65F5F", marker="o", + markersize=5, linewidth=2, zorder=3) + ax2.set_ylabel("Cumulative %", color="#D65F5F") + ax2.set_ylim(0, 105) + ax2.yaxis.set_major_formatter(mticker.PercentFormatter()) + ax2.tick_params(axis="y", labelcolor="#D65F5F") + + # annotate the top-N cumulative point + ax2.annotate( + f"{top_pct:.1f}%", + xy=(top_n - 1, cumulative[top_n - 1]), + xytext=(top_n - 1.5, cumulative[top_n - 1] - 10), + color="#D65F5F" + ) + + ax2.annotate( + f"{cumulative[4-1]:.1f}%", + xy=(4 - 1, cumulative[4 - 1]), + xytext=(4 - 1.5, cumulative[4 - 1] + 5), + color="#D65F5F" + ) + + n_invocations = df["invocation"].nunique() + ax1.set_title( + f"BB-Level Cycle Attribution — Top {top_n} BBs ({n_invocations} invocations)", + pad=12, + ) + + fig.tight_layout() + fig.savefig(output, dpi=200, bbox_inches="tight") + print(f"Saved to {output}") + print(f"--- Stats ---") + print(f"Invocations: {n_invocations}") + print(f"Total BB records: {len(df)}") + print(f"Unique BBs: {len(bb_agg)}") + print(f"Total cycles: {grand_total}") + print(f"Mean cycles/inv: {grand_total / n_invocations:.1f}") + print(f"Top {top_n} BBs: {top_pct:.1f}% of total cycles") + + +if __name__ == "__main__": + main() diff --git a/scripts/analysis/plot_iteration_breakdown.py b/scripts/analysis/plot_iteration_breakdown.py new file mode 100644 index 0000000..b6c8590 --- /dev/null +++ b/scripts/analysis/plot_iteration_breakdown.py @@ -0,0 +1,232 @@ +import matplotlib +import matplotlib.pyplot as plt +import numpy as np +import pandas as pd +import argparse + +matplotlib.rcParams.update({'font.size': 16}) + + +def _sci_fmt(x: float) -> str: + return f'{x:.2e}' + + +def plot_latency_distribution(df: pd.DataFrame, output_prefix: str) -> None: + times = df['total_cycles'].values + plt.figure(figsize=(10, 6)) + plt.hist(times, bins=50, alpha=0.8, weights=np.ones_like(times) / len(times) * 100) + + p50 = np.percentile(times, 50) + p90 = np.percentile(times, 90) + p95 = np.percentile(times, 95) + p99 = np.percentile(times, 99) + + plt.axvline(p50, color='green', linestyle='--', linewidth=1, label=f'p50 ({_sci_fmt(p50)})') + plt.axvline(p90, color='orange', linestyle='--', linewidth=1, label=f'p90 ({_sci_fmt(p90)})') + plt.axvline(p95, color='red', linestyle='--', linewidth=1, label=f'p95 ({_sci_fmt(p95)})') + plt.axvline(p99, color='darkviolet', linestyle='--', linewidth=1, label=f'p99 ({_sci_fmt(p99)})') + plt.legend() + plt.xlabel('Latency (cycles)') + plt.ylabel('Percentage (%)') + plt.title('Iteration Latency Distribution') + plt.tight_layout() + plt.savefig(f'{output_prefix}.latency_distribution.png') + plt.close() + + +def plot_prv_breakdown(df: pd.DataFrame, output_prefix: str) -> None: + fig, ax = plt.subplots(figsize=(12, 6)) + iters = df['iter'].values + ax.bar(iters, df['user_cycles'], label='User', color='#2196F3') + ax.bar(iters, df['supervisor_cycles'], bottom=df['user_cycles'], label='Supervisor', color='#FF9800') + ax.bar(iters, df['machine_cycles'], + bottom=df['user_cycles'] + df['supervisor_cycles'], label='Machine', color='#F44336') + ax.set_xlabel('Iteration') + ax.set_ylabel('Cycles') + ax.set_title('Per-Iteration Privilege Level Breakdown') + ax.legend() + plt.tight_layout() + plt.savefig(f'{output_prefix}.prv_breakdown.png') + plt.close() + + +def plot_tracked_func_impact(df: pd.DataFrame, tracked_func: str, output_prefix: str) -> None: + count_col = f'{tracked_func}_count' + cycles_col = f'{tracked_func}_cycles' + avg_col = f'{tracked_func}_avg_cycles' + + if count_col not in df.columns: + print(f'No {count_col} column found, skipping tracked function plots') + return + + df_with = df[df[count_col] > 0] + df_without = df[df[count_col] == 0] + + # Box plot: with vs without tracked function + fig, ax = plt.subplots(figsize=(8, 6)) + data = [d['total_cycles'].values for d in [df_without, df_with] if len(d) > 0] + labels = [] + if len(df_without) > 0: + labels.append(f'Without {tracked_func}\n(n={len(df_without)})') + if len(df_with) > 0: + labels.append(f'With {tracked_func}\n(n={len(df_with)})') + ax.boxplot(data, labels=labels) + ax.set_ylabel('Total Cycles') + ax.set_title(f'Impact of {tracked_func} on Iteration Latency') + plt.tight_layout() + plt.savefig(f'{output_prefix}.tracked_func_boxplot.png') + plt.close() + + if len(df_with) > 0: + # Scatter: tracked_func_cycles vs total_cycles (publication grade) + fig, ax = plt.subplots(figsize=(8, 6)) + x = df_with[cycles_col].values + y = df_with['total_cycles'].values + ax.scatter(x, y, alpha=0.5, s=25, edgecolors='none', color='#1f77b4', zorder=3) + + # Linear fit (excluding 1 max and 1 min by total_cycles to reduce outlier influence) + sort_idx = np.argsort(y) + trimmed = sort_idx[1:-1] + x_trim, y_trim = x[trimmed], y[trimmed] + coeffs = np.polyfit(x_trim, y_trim, 1) + x_fit = np.linspace(x.min(), x.max(), 100) + y_fit = np.polyval(coeffs, x_fit) + r2 = 1 - np.sum((y_trim - np.polyval(coeffs, x_trim)) ** 2) / np.sum((y_trim - y_trim.mean()) ** 2) + ax.plot(x_fit, y_fit, color='#d62728', linewidth=1.5, alpha=0.7, zorder=4, + label=f'Linear fit after outlier removal') + + ax.ticklabel_format(axis='x', style='scientific', scilimits=(0, 0)) + ax.grid(True, linestyle=':', linewidth=0.5, alpha=0.5) + ax.set_xlabel(f'{tracked_func} Total Cycles') + ax.set_ylabel('Total Iteration Cycles') + ax.set_title(f'{tracked_func} Cycles vs Iteration Latency', pad=15) + ax.legend() + plt.tight_layout() + plt.savefig(f'{output_prefix}.tracked_func_scatter.png', dpi=300) + plt.close() + + # Scatter: invocation count vs total_cycles + fig, ax = plt.subplots(figsize=(8, 6)) + ax.scatter(df_with[count_col], df_with['total_cycles'], alpha=0.6, s=20) + ax.set_xlabel(f'{tracked_func} Invocation Count') + ax.set_ylabel('Total Iteration Cycles') + ax.set_title(f'{tracked_func} Invocation Count vs Iteration Latency') + plt.tight_layout() + plt.savefig(f'{output_prefix}.tracked_func_count_scatter.png') + plt.close() + + +def plot_prv_comparison(df: pd.DataFrame, tracked_func: str, output_prefix: str) -> None: + count_col = f'{tracked_func}_count' + if count_col not in df.columns: + return + + df_with = df[df[count_col] > 0] + df_without = df[df[count_col] == 0] + if len(df_with) == 0 or len(df_without) == 0: + return + + groups = {'Without': df_without, 'With': df_with} + labels = list(groups.keys()) + user_pcts, sup_pcts, mach_pcts = [], [], [] + for group in groups.values(): + total = group['total_cycles'].mean() + user_pcts.append(group['user_cycles'].mean() / total * 100) + sup_pcts.append(group['supervisor_cycles'].mean() / total * 100) + mach_pcts.append(group['machine_cycles'].mean() / total * 100) + + fig, ax = plt.subplots(figsize=(8, 3)) + y = np.arange(len(labels)) + bar_height = 0.5 + + ax.barh(y, user_pcts, bar_height, label='User', color='#2196F3') + ax.barh(y, sup_pcts, bar_height, left=user_pcts, label='Supervisor', color='#FF9800') + ax.barh(y, mach_pcts, bar_height, + left=[u + s for u, s in zip(user_pcts, sup_pcts)], label='Machine', color='#F44336') + + ax.set_yticks(y) + ax.set_yticklabels([f'{l} {tracked_func}\n(n={len(g)})' for l, g in zip(labels, groups.values())]) + ax.set_xlabel('Percentage of Total Cycles (%)') + ax.set_xlim(0, 100) + ax.set_title(f'Privilege Level Breakdown: With vs Without {tracked_func}') + ax.legend(loc='upper left', bbox_to_anchor=(1.01, 1)) + plt.tight_layout() + plt.savefig(f'{output_prefix}.prv_comparison.png') + plt.close() + + +def print_summary(df: pd.DataFrame, tracked_func: str) -> None: + times = df['total_cycles'] + print('=' * 60) + print('Iteration Breakdown Summary') + print('=' * 60) + print(f' Iterations: {len(df)}') + print(f' Min: {times.min()}') + print(f' Max: {times.max()}') + print(f' Mean: {times.mean():.0f}') + print(f' Std: {times.std():.0f}') + print(f' Median: {times.median():.0f}') + print(f' p90: {np.percentile(times, 90):.0f}') + print(f' p95: {np.percentile(times, 95):.0f}') + print(f' p99: {np.percentile(times, 99):.0f}') + print() + print('Privilege level breakdown (mean across iterations):') + for col in ['user_cycles', 'supervisor_cycles', 'machine_cycles']: + pct = df[col].mean() / times.mean() * 100 + print(f' {col:25s}: {df[col].mean():12.0f} ({pct:5.1f}%)') + + count_col = f'{tracked_func}_count' + cycles_col = f'{tracked_func}_cycles' + avg_col = f'{tracked_func}_avg_cycles' + if count_col in df.columns: + df_with = df[df[count_col] > 0] + df_without = df[df[count_col] == 0] + n_with = len(df_with) + n_total = len(df) + print() + print(f'{tracked_func} impact:') + print(f' Iterations with {tracked_func}: {n_with}/{n_total} ({n_with/n_total*100:.1f}%)') + if n_with > 0: + mean_with = df_with['total_cycles'].mean() + mean_without = df_without['total_cycles'].mean() if len(df_without) > 0 else 0 + mean_count = df_with[count_col].mean() + mean_total_cycles = df_with[cycles_col].mean() + mean_avg_cycles = df_with[avg_col].mean() + print(f' Mean latency with: {mean_with:.0f}') + if len(df_without) > 0: + print(f' Mean latency without: {mean_without:.0f}') + print(f' Mean overhead: {mean_with - mean_without:.0f} ({(mean_with - mean_without) / mean_without * 100:.1f}%)') + print(f' Mean invocations/iter: {mean_count:.1f}') + print(f' Mean total cycles/iter: {mean_total_cycles:.0f}') + print(f' Mean cycles/invocation: {mean_avg_cycles:.0f}') + print() + print(f'Privilege level comparison (with vs without {tracked_func}):') + for label, group in [('With', df_with), ('Without', df_without)]: + if len(group) == 0: + continue + u_pct = group['user_cycles'].mean() / group['total_cycles'].mean() * 100 + s_pct = group['supervisor_cycles'].mean() / group['total_cycles'].mean() * 100 + m_pct = group['machine_cycles'].mean() / group['total_cycles'].mean() * 100 + print(f' {label:10s} user={u_pct:5.1f}% supervisor={s_pct:5.1f}% machine={m_pct:5.1f}%') + if len(df_with) > 0 and len(df_without) > 0: + for col, name in [('user_cycles', 'user'), ('supervisor_cycles', 'supervisor'), ('machine_cycles', 'machine')]: + pct_with = df_with[col].mean() / df_with['total_cycles'].mean() * 100 + pct_without = df_without[col].mean() / df_without['total_cycles'].mean() * 100 + print(f' Delta {name:12s}: {pct_with - pct_without:+.1f}pp') + print('=' * 60) + + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description='Plot iteration breakdown analysis') + parser.add_argument('--iterations', type=str, required=True, help='Path to iteration_breakdown CSV') + parser.add_argument('--tracked-func', type=str, default='rcu_do_batch', help='Name of tracked function') + parser.add_argument('--output-prefix', type=str, default='iteration', help='Output file prefix') + args = parser.parse_args() + + df = pd.read_csv(args.iterations) + print_summary(df, args.tracked_func) + plot_latency_distribution(df, args.output_prefix) + plot_prv_breakdown(df, args.output_prefix) + plot_tracked_func_impact(df, args.tracked_func, args.output_prefix) + plot_prv_comparison(df, args.tracked_func, args.output_prefix) + print(f'Plots saved to {args.output_prefix}.*.png') diff --git a/scripts/analysis/plot_post_exit.py b/scripts/analysis/plot_post_exit.py new file mode 100644 index 0000000..ecdeec8 --- /dev/null +++ b/scripts/analysis/plot_post_exit.py @@ -0,0 +1,57 @@ +import pandas as pd +import matplotlib.pyplot as plt +import matplotlib +import sys + +matplotlib.rcParams.update({'font.size': 16}) + +def main(): + if len(sys.argv) < 2: + print("Usage: python plot_post_exit.py [output_png]") + sys.exit(1) + + csv_path = sys.argv[1] + output = sys.argv[2] if len(sys.argv) > 2 else "func_path_post_exit.png" + + df = pd.read_csv(csv_path) + df.columns = df.columns.str.strip() + + max_idx = df["bb_index"].max() + # prepare data for box plot + data = [df[df["bb_index"] == i]["duration"].values for i in range(max_idx + 1)] + + fig, ax = plt.subplots(figsize=(8, 5)) + ax.scatter(df["bb_index"], df["duration"], alpha=0.3, s=10, color="#4878CF") + + + # box plot + # bp = ax.boxplot(data, positions=range(max_idx + 1), widths=0.5, + # patch_artist=True, showfliers=True, + # flierprops=dict(marker='.', markersize=4, alpha=0.5, color="#999999"), + # medianprops=dict(color="white", linewidth=2), + # whiskerprops=dict(color="#4878CF"), + # capprops=dict(color="#4878CF")) + # for box in bp["boxes"]: + # box.set_facecolor("#4878CF") + # box.set_alpha(0.7) + + # mean line + means = df.groupby("bb_index")["duration"].mean() + ax.plot(means.index, means.values, color="#D65F5F", marker="o", + markersize=5, linewidth=2, label="mean", zorder=5, alpha=0.7) + + ax.set_xlabel("BB Index After Trap Return") + ax.set_ylabel("Duration (cycles)") + ax.set_xticks(range(max_idx + 1)) + ax.grid(axis="y", alpha=0.3) + ax.legend() + + n_inv = df["invocation"].nunique() + ax.set_title(f"Post-Trap Return BB Latency", pad=12) + + fig.tight_layout() + fig.savefig(output, dpi=200, bbox_inches="tight") + print(f"Saved to {output}") + +if __name__ == "__main__": + main() diff --git a/scripts/analysis/plot_vbb.sh b/scripts/analysis/plot_vbb.sh new file mode 100755 index 0000000..186c839 --- /dev/null +++ b/scripts/analysis/plot_vbb.sh @@ -0,0 +1,37 @@ +#!/bin/bash + +# a list of workloads to process +WORKLOADS=( + trace.perlbench_s.sqlite.db + trace.mcf_s.sqlite.db + trace.gcc_s.sqlite.db + trace.x264_s.sqlite.db + trace.omnetpp_s.sqlite.db + trace.xalancbmk_s.sqlite.db + trace.leela_s.sqlite.db + trace.xz_s-cpu2006docs.sqlite.db + trace.xz_s-cld.sqlite.db + trace.exchange2_s.sqlite.db +) + +NAMES=( + "perlbench" + "mcf" + "gcc" + "x264" + "omnetpp" + "xalancbmk" + "leela" + "xz-cpu2006docs" + "xz-cld" + "exchange2" +) + +cd /scratch/iansseijelly/tacit-chipyard/software/tacit_decoder + +for i in "${!WORKLOADS[@]}"; do + workload=${WORKLOADS[i]} + name=${NAMES[i]} + echo "Processing $workload to $name" + ./target/release/trace_db_tools bb-stats --db /scratch/iansseijelly/spec-db/$workload --outdir /scratch/iansseijelly/spec-path-profiles-vbb/$name --prv 0 --limit 10 +done \ No newline at end of file diff --git a/scripts/analysis/quantify_error.py b/scripts/analysis/quantify_error.py index 73b65ed..dbf7a7a 100644 --- a/scripts/analysis/quantify_error.py +++ b/scripts/analysis/quantify_error.py @@ -1,39 +1,11 @@ """ -Given two per-basic block delta CSV files, quantify delta error. +Given a per-basic block emulation CSV with reference_delta and emulated_delta columns, +quantify the emulation error. """ import argparse import csv -REQUIRED_COLUMNS = {"delta", "event"} - - -def load_rows(path: str): - rows = [] - with open(path, "r", encoding="utf-8", newline="") as f: - reader = csv.DictReader(f) - if reader.fieldnames is None: - raise ValueError(f"{path}: missing CSV header") - missing = REQUIRED_COLUMNS - set(reader.fieldnames) - if missing: - raise ValueError( - f"{path}: missing required column(s): {', '.join(sorted(missing))}" - ) - - for row_idx, row in enumerate(reader, 2): - event = (row.get("event") or "").strip() - # src = (row.get("from") or "").strip() - # dst = (row.get("to") or "").strip() - delta_str = (row.get("delta") or "").strip() - try: - delta = int(delta_str) - except ValueError as exc: - raise ValueError( - f"{path}:{row_idx}: invalid delta value: {delta_str}" - ) from exc - rows.append({"delta": delta, "event": event}) - return rows - def variance(values): mean = sum(values) / len(values) @@ -42,53 +14,47 @@ def variance(values): def main(): parser = argparse.ArgumentParser() - parser.add_argument("--golden", type=str, required=True) - parser.add_argument("--measured", type=str, required=True) + parser.add_argument("--input", type=str, required=True, help="CSV with reference_delta and emulated_delta columns") args = parser.parse_args() - golden_rows = load_rows(args.golden) - measured_rows = load_rows(args.measured) + abs_errors = [] + ref_deltas = [] + emu_deltas = [] - if len(measured_rows) > len(golden_rows): - raise ValueError( - f"Measured has more rows than golden: {len(measured_rows)} > {len(golden_rows)}" - ) - if not measured_rows: - raise ValueError("Measured trace is empty.") + with open(args.input, "r", encoding="utf-8", newline="") as f: + reader = csv.DictReader(f) + for row_idx, row in enumerate(reader, 2): + try: + ref = int(row["reference_delta"]) + emu = int(row["emulated_delta"]) + except (KeyError, ValueError) as exc: + raise ValueError(f"{args.input}:{row_idx}: invalid row: {row}") from exc + abs_errors.append(abs(ref - emu)) + ref_deltas.append(ref) + emu_deltas.append(emu) - abs_errors = [] - golden_deltas = [] - measured_deltas = [] - for idx, measured_row in enumerate(measured_rows, 1): - golden_row = golden_rows[idx - 1] - golden_rest = (golden_row["event"]) - measured_rest = (measured_row["event"]) - if golden_rest != measured_rest: - raise ValueError( - f"Row {idx} mismatch: golden={golden_rest}, measured={measured_rest}" - ) - abs_errors.append(abs(golden_row["delta"] - measured_row["delta"])) - golden_deltas.append(golden_row["delta"]) - measured_deltas.append(measured_row["delta"]) + if not ref_deltas: + raise ValueError("Input is empty.") mae = sum(abs_errors) / len(abs_errors) total_error = sum(abs_errors) - total_time = sum(golden_deltas) - var_golden = variance(golden_deltas) - var_measured = variance(measured_deltas) - var_ratio = float("inf") if var_golden == 0 else var_measured / var_golden + total_time = sum(ref_deltas) + var_ref = variance(ref_deltas) + var_emu = variance(emu_deltas) + var_ratio = float("inf") if var_ref == 0 else var_emu / var_ref weighted_error = float("inf") if total_time == 0 else total_error / total_time - print(f"MAE: {mae:.6f}") + print(f"Events: {len(ref_deltas)}") + print(f"MAE: {mae:.6f}") if var_ratio == float("inf"): - print("VarRatio: inf") + print("VarRatio: inf") else: - print(f"VarRatio: {var_ratio:.6f}") + print(f"VarRatio: {var_ratio:.6f}") if weighted_error == float("inf"): print("WeightedError: inf") else: - print(f"TotalError: {total_error:.6f}") - print(f"TotalTime: {total_time:.6f}") + print(f"TotalError: {total_error}") + print(f"TotalTime: {total_time}") print(f"WeightedError: {weighted_error * 100:.4f}%") diff --git a/scripts/analysis/quantify_error_twofiles.py b/scripts/analysis/quantify_error_twofiles.py new file mode 100644 index 0000000..73b65ed --- /dev/null +++ b/scripts/analysis/quantify_error_twofiles.py @@ -0,0 +1,96 @@ +""" +Given two per-basic block delta CSV files, quantify delta error. +""" + +import argparse +import csv + +REQUIRED_COLUMNS = {"delta", "event"} + + +def load_rows(path: str): + rows = [] + with open(path, "r", encoding="utf-8", newline="") as f: + reader = csv.DictReader(f) + if reader.fieldnames is None: + raise ValueError(f"{path}: missing CSV header") + missing = REQUIRED_COLUMNS - set(reader.fieldnames) + if missing: + raise ValueError( + f"{path}: missing required column(s): {', '.join(sorted(missing))}" + ) + + for row_idx, row in enumerate(reader, 2): + event = (row.get("event") or "").strip() + # src = (row.get("from") or "").strip() + # dst = (row.get("to") or "").strip() + delta_str = (row.get("delta") or "").strip() + try: + delta = int(delta_str) + except ValueError as exc: + raise ValueError( + f"{path}:{row_idx}: invalid delta value: {delta_str}" + ) from exc + rows.append({"delta": delta, "event": event}) + return rows + + +def variance(values): + mean = sum(values) / len(values) + return sum((v - mean) ** 2 for v in values) / len(values) + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("--golden", type=str, required=True) + parser.add_argument("--measured", type=str, required=True) + args = parser.parse_args() + + golden_rows = load_rows(args.golden) + measured_rows = load_rows(args.measured) + + if len(measured_rows) > len(golden_rows): + raise ValueError( + f"Measured has more rows than golden: {len(measured_rows)} > {len(golden_rows)}" + ) + if not measured_rows: + raise ValueError("Measured trace is empty.") + + abs_errors = [] + golden_deltas = [] + measured_deltas = [] + for idx, measured_row in enumerate(measured_rows, 1): + golden_row = golden_rows[idx - 1] + golden_rest = (golden_row["event"]) + measured_rest = (measured_row["event"]) + if golden_rest != measured_rest: + raise ValueError( + f"Row {idx} mismatch: golden={golden_rest}, measured={measured_rest}" + ) + abs_errors.append(abs(golden_row["delta"] - measured_row["delta"])) + golden_deltas.append(golden_row["delta"]) + measured_deltas.append(measured_row["delta"]) + + mae = sum(abs_errors) / len(abs_errors) + total_error = sum(abs_errors) + total_time = sum(golden_deltas) + var_golden = variance(golden_deltas) + var_measured = variance(measured_deltas) + var_ratio = float("inf") if var_golden == 0 else var_measured / var_golden + weighted_error = float("inf") if total_time == 0 else total_error / total_time + + print(f"MAE: {mae:.6f}") + if var_ratio == float("inf"): + print("VarRatio: inf") + else: + print(f"VarRatio: {var_ratio:.6f}") + if weighted_error == float("inf"): + print("WeightedError: inf") + else: + print(f"TotalError: {total_error:.6f}") + print(f"TotalTime: {total_time:.6f}") + print(f"WeightedError: {weighted_error * 100:.4f}%") + + +if __name__ == "__main__": + main() diff --git a/scripts/config/populate_asids_from_log.py b/scripts/config/populate_asids_from_log.py new file mode 100755 index 0000000..c36f4b9 --- /dev/null +++ b/scripts/config/populate_asids_from_log.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python3 +"""Extract ASIDs from a uartlog and populate a tacit_decoder config JSON.""" + +import argparse +import json +import re +import sys + + +def main(): + parser = argparse.ArgumentParser( + description="Extract ASIDs from uartlog and populate config JSON." + ) + parser.add_argument("--uartlog", help="Path to the uartlog file") + parser.add_argument("--config", help="Path to the tacit_decoder config JSON") + parser.add_argument("--binary_name", help="Binary comm name to filter for (e.g. perlbench_s_bas)") + args = parser.parse_args() + + # Extract matching ASIDs from the log + pattern = re.compile(r"^tacit: asid=(\d+) pid=\d+ comm=(.+)$") + asids = [] + with open(args.uartlog) as f: + for line in f: + line = line.strip() + m = pattern.match(line) + if m and m.group(2) == args.binary_name: + asids.append(int(m.group(1))) + + if not asids: + print(f"Warning: no ASIDs found for '{args.binary_name}'", file=sys.stderr) + + asids = sorted(set(asids)) + print(f"Found {len(asids)} unique ASIDs for '{args.binary_name}': {asids}") + + # Update the config + with open(args.config) as f: + config = json.load(f) + + for entry in config.get("user_binaries", []): + entry["asids"] = asids + + with open(args.config, "w") as f: + json.dump(config, f, indent=2) + f.write("\n") + + print(f"Updated {args.config}") + + +if __name__ == "__main__": + main() diff --git a/scripts/run_spec_decode_all.sh b/scripts/run_spec_decode_all.sh new file mode 100755 index 0000000..992f9b4 --- /dev/null +++ b/scripts/run_spec_decode_all.sh @@ -0,0 +1,22 @@ +#!/bin/bash +benchmarks=( + "600_perlbench" + "602_gcc" + "605_mcf" + "620_omnetpp" + "623_xalancbmk" + "625_x264" + "641_leela" + "648_exchange2" + "657_xz_cld" + "657_xz_cpu2006docs" +) + +mkdir -p trace_errors + +echo $(pwd) + +for benchmark in "${benchmarks[@]}"; do + echo "Decoding $benchmark" + ./target/release/tacit-decoder --config configs/spec-emulation/linux_$benchmark.json > trace_errors/$benchmark.txt 2>&1 +done \ No newline at end of file diff --git a/scripts/sql/bb_stats.py b/scripts/sql/bb_stats.py new file mode 100644 index 0000000..cfd070b --- /dev/null +++ b/scripts/sql/bb_stats.py @@ -0,0 +1,98 @@ +import sqlite3 +import csv +import argparse +import sys +from collections import defaultdict +from tqdm import tqdm + + +def to_u64(val: int) -> int: + """Convert signed i64 (from SQLite) back to unsigned u64.""" + return val & 0xFFFFFFFFFFFFFFFF + + +def bb_stats(db_path: str, output: str, prv: int | None, ctx: int | None, limit: int | None) -> None: + conn = sqlite3.connect(db_path) + + # Always scan all events to get correct deltas; filter prv/ctx in Python + sql_where = "event_type NOT IN ('SYNC_START', 'SYNC_END')" + + count_query = f"SELECT COUNT(*) FROM events WHERE {sql_where}" + total_rows = conn.execute(count_query).fetchone()[0] + + query = f"SELECT timestamp, from_addr, to_addr, prv, ctx FROM events WHERE {sql_where} ORDER BY id" + cursor = conn.execute(query) + + # Streaming aggregation: track (count, sum, min) per BB + bb_agg = defaultdict(lambda: [0, 0, float('inf')]) # [count, sum, min] + prev_ts = None + prev_to = None + prev_matches = False + + for timestamp, from_addr, to_addr, row_prv, row_ctx in tqdm(cursor, total=total_rows, desc="Scanning", unit="events"): + from_addr = to_u64(from_addr) + to_addr = to_u64(to_addr) + curr_matches = (prv is None or row_prv == prv) and (ctx is None or row_ctx == ctx) + if prev_ts is not None and prev_matches and curr_matches: + delta = timestamp - prev_ts + bb = (prev_to, from_addr) + agg = bb_agg[bb] + agg[0] += 1 + agg[1] += delta + if delta < agg[2]: + agg[2] = delta + prev_ts = timestamp + prev_to = to_addr + prev_matches = curr_matches + + conn.close() + print(f"Aggregated {len(bb_agg)} unique BBs", file=sys.stderr) + + # Sort by netvar descending + results = [] + for (bb_start, bb_end), (count, total, min_delta) in bb_agg.items(): + mean = total / count + netvar = total - min_delta * count + results.append((count, mean, netvar, bb_start, bb_end)) + results.sort(key=lambda r: r[2], reverse=True) + + if limit: + results = results[:limit] + + with open(output, 'w', newline='') as f: + writer = csv.writer(f) + writer.writerow(['count', 'mean', 'netvar', 'bb']) + for count, mean, netvar, bb_start, bb_end in results: + writer.writerow([count, f'{mean:.1f}', netvar, f'{bb_start:#x}-{bb_end:#x}']) + + print(f"Written {len(results)} rows to {output}", file=sys.stderr) + + # Summary stats + total_cycles = sum(r[1] * r[0] for r in results) # mean * count = total per BB + total_netvar = sum(r[2] for r in results) + total_events = sum(r[0] for r in results) + print(f"\n{'='*60}", file=sys.stderr) + print(f"BB Stats Summary", file=sys.stderr) + print(f"{'='*60}", file=sys.stderr) + print(f" Events scanned: {total_rows}", file=sys.stderr) + print(f" Unique BBs: {len(bb_agg)}", file=sys.stderr) + print(f" Total cycles: {total_cycles:.0f}", file=sys.stderr) + print(f" Total netvar: {total_netvar:.0f}", file=sys.stderr) + if results: + top = results[0] + print(f" Top BB by netvar: {top[3]:#x}-{top[4]:#x} (netvar={top[2]}, count={top[0]}, mean={top[1]:.1f})", file=sys.stderr) + top10_netvar = sum(r[2] for r in results[:10]) + print(f" Top 10 netvar: {top10_netvar:.0f} ({top10_netvar/total_netvar*100:.1f}% of total)", file=sys.stderr) + print(f"{'='*60}", file=sys.stderr) + + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description='Compute BB stats from SQLite trace DB') + parser.add_argument('--db', type=str, default='trace.db', help='Path to SQLite trace DB') + parser.add_argument('--output', type=str, default='trace.bb_stats.csv', help='Output CSV path') + parser.add_argument('--prv', type=int, default=None, help='Filter by privilege level (0=user, 1=supervisor, 3=machine)') + parser.add_argument('--ctx', type=int, default=None, help='Filter by ASID context') + parser.add_argument('--limit', type=int, default=None, help='Limit number of output rows') + args = parser.parse_args() + + bb_stats(args.db, args.output, args.prv, args.ctx, args.limit) diff --git a/src/backend/event.rs b/src/backend/event.rs index 77c5a10..abb0524 100644 --- a/src/backend/event.rs +++ b/src/backend/event.rs @@ -223,8 +223,8 @@ impl std::fmt::Display for EventKind { ctx, } => write!( f, - "Trap: {:#x} -> {:#x} ({:?} {:?})", - arc.0, arc.1, reason, prv_arc + "Trap: {:#x} -> {:#x} ({:?} {:?}) (ctx: {:?})", + arc.0, arc.1, reason, prv_arc, ctx ), EventKind::SyncStart { runtime_cfg, diff --git a/src/main.rs b/src/main.rs index 86be0e9..4627007 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,6 +6,7 @@ extern crate indicatif; extern crate log; extern crate object; extern crate rustc_data_structures; +extern crate rusqlite; extern crate rvdasm; mod frontend { @@ -102,7 +103,7 @@ fn main() -> Result<()> { || !Path::new(&static_cfg.machine_binary).is_file()) { return Err(anyhow::anyhow!( - "SBI binary file is not valid: {}", + "Machine binary file is not valid: {}", static_cfg.machine_binary )); } diff --git a/src/receivers/analysis/func_path_receiver.rs b/src/receivers/analysis/func_path_receiver.rs new file mode 100644 index 0000000..9c9fe2f --- /dev/null +++ b/src/receivers/analysis/func_path_receiver.rs @@ -0,0 +1,397 @@ +use crate::backend::event::{Entry, EventKind}; +use crate::common::symbol_index::SymbolIndex; +use crate::receivers::abstract_receiver::{AbstractReceiver, BusReceiver, Shared}; +use crate::receivers::stack_unwinder::StackUnwinder; +use bus::BusReader; +use std::collections::HashMap; +use std::fs::File; +use std::io::{BufWriter, Write}; +use std::sync::Arc; + +struct PathStats { + count: u64, + min: u64, + sum: u64, +} + +impl PathStats { + fn new(duration: u64) -> Self { + Self { + count: 1, + min: duration, + sum: duration, + } + } + + fn update(&mut self, duration: u64) { + self.count += 1; + self.min = self.min.min(duration); + self.sum += duration; + } +} + +struct BBRecord { + start: u64, + end: u64, + duration: u64, +} + +struct Invocation { + bbs: Vec, +} + +enum Phase { + Idle, + Active, + PostExit { remaining: usize }, +} + +pub struct FuncPathReceiver { + path_writer: BufWriter, + bb_writer: BufWriter, + post_exit_writer: BufWriter, + receiver: BusReceiver, + unwinder: StackUnwinder, + func_name: String, + ctx: u64, + filter_contains: Option, + phase: Phase, + entry_ts: u64, + seen_filter: bool, + current_branches: Vec, + path_records: HashMap, PathStats>, + // per-invocation BB tracking + prev_addr: u64, + prev_timestamp: u64, + current_bbs: Vec, + invocations: Vec, + // post-exit BB tracking + post_exit_n: usize, + post_exit_bbs: Vec, + post_exit_records: Vec>, +} + +impl FuncPathReceiver { + pub fn new( + bus_rx: BusReader, + symbols: Arc, + func_name: String, + ctx: u64, + filter_contains: Option, + path: String, + bb_path: String, + post_exit_path: String, + post_exit_n: usize, + ) -> Self { + Self { + path_writer: BufWriter::new(File::create(path).unwrap()), + bb_writer: BufWriter::new(File::create(bb_path).unwrap()), + post_exit_writer: BufWriter::new(File::create(post_exit_path).unwrap()), + receiver: BusReceiver { + name: "func_path".to_string(), + bus_rx, + checksum: 0, + }, + unwinder: StackUnwinder::new(symbols).expect("stack unwinder"), + func_name, + ctx, + filter_contains, + phase: Phase::Idle, + entry_ts: 0, + seen_filter: false, + current_branches: Vec::new(), + path_records: HashMap::new(), + prev_addr: 0, + prev_timestamp: 0, + current_bbs: Vec::new(), + invocations: Vec::new(), + post_exit_n, + post_exit_bbs: Vec::new(), + post_exit_records: Vec::new(), + } + } + + fn close_bb(&mut self, from_addr: u64, to_addr: u64, timestamp: u64) { + let duration = timestamp.saturating_sub(self.prev_timestamp); + self.current_bbs.push(BBRecord { + start: self.prev_addr, + end: from_addr, + duration, + }); + self.prev_addr = to_addr; + self.prev_timestamp = timestamp; + } + + fn commit_post_exit(&mut self) { + self.post_exit_records + .push(std::mem::take(&mut self.post_exit_bbs)); + self.phase = Phase::Idle; + } + + fn close_post_exit_bb(&mut self, from_addr: u64, to_addr: u64, timestamp: u64) { + let duration = timestamp.saturating_sub(self.prev_timestamp); + self.post_exit_bbs.push(BBRecord { + start: self.prev_addr, + end: from_addr, + duration, + }); + self.prev_addr = to_addr; + self.prev_timestamp = timestamp; + } + + fn commit_invocation(&mut self, exit_ts: u64) { + let dominated = match &self.filter_contains { + Some(_) => self.seen_filter, + None => true, + }; + if dominated { + let duration = exit_ts.saturating_sub(self.entry_ts); + let branches = std::mem::take(&mut self.current_branches); + if let Some(stats) = self.path_records.get_mut(&branches) { + stats.update(duration); + } else { + self.path_records.insert(branches, PathStats::new(duration)); + } + self.invocations.push(Invocation { + bbs: std::mem::take(&mut self.current_bbs), + }); + // transition to post-exit tracking + self.post_exit_bbs.clear(); + self.phase = Phase::PostExit { + remaining: self.post_exit_n, + }; + } else { + self.current_branches.clear(); + self.current_bbs.clear(); + self.phase = Phase::Idle; + } + self.seen_filter = false; + } +} + +pub fn factory( + shared: &Shared, + config: serde_json::Value, + bus_rx: BusReader, +) -> Box { + let func_name = config + .get("func_name") + .and_then(|v| v.as_str()) + .unwrap_or("") + .to_string(); + let ctx = config + .get("ctx") + .and_then(|v| v.as_u64()) + .unwrap_or(0); + let filter_contains = config + .get("filter_contains") + .and_then(|v| v.as_str()) + .map(|s| s.to_string()); + let path = config + .get("path") + .and_then(|v| v.as_str()) + .unwrap_or("trace.func_path.csv") + .to_string(); + let bb_path = config + .get("bb_path") + .and_then(|v| v.as_str()) + .unwrap_or("trace.func_path.bb.csv") + .to_string(); + let post_exit_path = config + .get("post_exit_path") + .and_then(|v| v.as_str()) + .unwrap_or("trace.func_path.post_exit.csv") + .to_string(); + let post_exit_n = config + .get("post_exit_n") + .and_then(|v| v.as_u64()) + .unwrap_or(10) as usize; + Box::new(FuncPathReceiver::new( + bus_rx, + shared.symbol_index.clone(), + func_name, + ctx, + filter_contains, + path, + bb_path, + post_exit_path, + post_exit_n, + )) +} + +crate::register_receiver!("func_path", factory); + +impl AbstractReceiver for FuncPathReceiver { + fn bus_rx(&mut self) -> &mut BusReader { + &mut self.receiver.bus_rx + } + + fn _bump_checksum(&mut self) { + self.receiver.checksum += 1; + } + + fn _receive_entry(&mut self, entry: Entry) { + match entry { + Entry::Instruction { .. } => {} + Entry::Event { timestamp, kind } => { + // Close BBs based on current phase + match self.phase { + Phase::Active => { + match &kind { + EventKind::TakenBranch { arc } => { + self.current_branches.push(true); + self.close_bb(arc.0, arc.1, timestamp); + } + EventKind::NonTakenBranch { arc } => { + self.current_branches.push(false); + self.close_bb(arc.0, arc.1, timestamp); + } + EventKind::InferrableJump { arc } => { + self.close_bb(arc.0, arc.1, timestamp); + } + EventKind::UninferableJump { arc } => { + self.close_bb(arc.0, arc.1, timestamp); + } + EventKind::Trap { arc, .. } => { + self.close_bb(arc.0, arc.1, timestamp); + } + _ => {} + } + } + Phase::PostExit { remaining } => { + let has_arc = matches!( + &kind, + EventKind::TakenBranch { .. } + | EventKind::NonTakenBranch { .. } + | EventKind::InferrableJump { .. } + | EventKind::UninferableJump { .. } + | EventKind::Trap { .. } + ); + if has_arc { + match &kind { + EventKind::TakenBranch { arc } + | EventKind::NonTakenBranch { arc } + | EventKind::InferrableJump { arc } + | EventKind::UninferableJump { arc } => { + self.close_post_exit_bb(arc.0, arc.1, timestamp); + } + EventKind::Trap { arc, .. } => { + self.close_post_exit_bb(arc.0, arc.1, timestamp); + } + _ => {} + } + let remaining = remaining - 1; + if remaining == 0 { + self.commit_post_exit(); + } else { + self.phase = Phase::PostExit { remaining }; + } + } + } + Phase::Idle => {} + } + + // Feed to stack unwinder + let update = self.unwinder.step(&Entry::Event { timestamp, kind }); + + if let Some(ref upd) = update { + // Check for target function exit (only when Active) + if matches!(self.phase, Phase::Active) { + for frame in &upd.frames_closed { + if frame.symbol.name == self.func_name { + self.commit_invocation(timestamp); + break; + } + } + } + + // Check for target function entry + if let Some(ref frame) = upd.frames_opened { + if !matches!(self.phase, Phase::Active) + && frame.symbol.name == self.func_name + && self.unwinder.curr_ctx == self.ctx + { + // If in PostExit, commit whatever we have + if matches!(self.phase, Phase::PostExit { .. }) { + self.commit_post_exit(); + } + self.phase = Phase::Active; + self.entry_ts = timestamp; + self.prev_addr = frame.addr; + self.prev_timestamp = timestamp; + self.current_branches.clear(); + self.current_bbs.clear(); + self.seen_filter = false; + } + if matches!(self.phase, Phase::Active) { + if let Some(ref filter) = self.filter_contains { + if frame.symbol.name == *filter { + self.seen_filter = true; + } + } + } + } + } + } + } + } + + fn _flush(&mut self) { + // Write path summary + writeln!(self.path_writer, "count,mean,netvar,path").unwrap(); + for (branches, stats) in self.path_records.iter() { + let mean = stats.sum as f64 / stats.count as f64; + let netvar = stats.sum as f64 - (stats.count as f64 * stats.min as f64); + let path_str: String = branches + .iter() + .map(|b| if *b { '1' } else { '0' }) + .collect(); + writeln!( + self.path_writer, + "{},{},{},{}", + stats.count, mean, netvar, path_str + ) + .unwrap(); + } + self.path_writer.flush().unwrap(); + + // Write per-invocation BB details + writeln!(self.bb_writer, "invocation,bb_start,bb_end,duration").unwrap(); + for (i, inv) in self.invocations.iter().enumerate() { + for bb in &inv.bbs { + writeln!( + self.bb_writer, + "{},{:#x},{:#x},{}", + i, bb.start, bb.end, bb.duration + ) + .unwrap(); + } + } + self.bb_writer.flush().unwrap(); + + // Write post-exit BB details + writeln!(self.post_exit_writer, "invocation,bb_index,bb_start,bb_end,duration").unwrap(); + for (i, bbs) in self.post_exit_records.iter().enumerate() { + for (j, bb) in bbs.iter().enumerate() { + writeln!( + self.post_exit_writer, + "{},{},{:#x},{:#x},{}", + i, j, bb.start, bb.end, bb.duration + ) + .unwrap(); + } + } + self.post_exit_writer.flush().unwrap(); + + println!("--------------------------------"); + println!( + "func_path: {} unique paths, {} invocations of '{}' (ctx={}) (filter=contains '{}')", + self.path_records.len(), + self.invocations.len(), + self.func_name, + self.ctx, + self.filter_contains.as_ref().unwrap_or(&"none".to_string()) + ); + println!("--------------------------------"); + } +} diff --git a/src/receivers/analysis/iteration_breakdown_receiver.rs b/src/receivers/analysis/iteration_breakdown_receiver.rs new file mode 100644 index 0000000..3d11836 --- /dev/null +++ b/src/receivers/analysis/iteration_breakdown_receiver.rs @@ -0,0 +1,282 @@ +use crate::backend::event::{Entry, EventKind}; +use crate::common::prv::Prv; +use crate::common::symbol_index::SymbolIndex; +use crate::receivers::abstract_receiver::{AbstractReceiver, BusReceiver, Shared}; +use crate::receivers::stack_unwinder::StackUnwinder; +use bus::BusReader; +use log::warn; +use std::fs::File; +use std::io::{BufWriter, Write}; +use std::sync::Arc; + +struct IterationState { + start_ts: u64, + user_cycles: u64, + supervisor_cycles: u64, + machine_cycles: u64, + tracked_func_count: u64, + tracked_func_cycles: u64, +} + +pub struct IterationBreakdownReceiver { + writer: BufWriter, + receiver: BusReceiver, + unwinder: StackUnwinder, + marker_func: String, + tracked_func: String, + marker_exit_count: usize, + in_iteration: bool, + in_tracked_func: bool, + tracked_func_entry_ts: u64, + current_iter: Option, + completed_iters: Vec<(IterationState, u64)>, // (state, end_ts) + curr_prv: Prv, + prev_timestamp: u64, +} + +impl IterationBreakdownReceiver { + pub fn new( + bus_rx: BusReader, + symbol_index: Arc, + marker_func: String, + tracked_func: String, + csv_path: String, + ) -> Self { + Self { + writer: BufWriter::new(File::create(&csv_path).unwrap()), + receiver: BusReceiver { + name: "iteration_breakdown".to_string(), + bus_rx, + checksum: 0, + }, + unwinder: StackUnwinder::new(symbol_index).unwrap(), + marker_func, + tracked_func, + marker_exit_count: 0, + in_iteration: false, + in_tracked_func: false, + tracked_func_entry_ts: 0, + current_iter: None, + completed_iters: Vec::new(), + curr_prv: Prv::PrvMachine, + prev_timestamp: 0, + } + } + + fn update_prv_cycles(&mut self, timestamp: u64) { + if !self.in_iteration { + return; + } + if let Some(ref mut iter_state) = self.current_iter { + let delta = timestamp.saturating_sub(self.prev_timestamp); + match self.curr_prv { + Prv::PrvUser => iter_state.user_cycles += delta, + Prv::PrvSupervisor => iter_state.supervisor_cycles += delta, + Prv::PrvMachine => iter_state.machine_cycles += delta, + _ => {} + } + } + } + + fn start_iteration(&mut self, timestamp: u64) { + self.in_iteration = true; + self.current_iter = Some(IterationState { + start_ts: timestamp, + user_cycles: 0, + supervisor_cycles: 0, + machine_cycles: 0, + tracked_func_count: 0, + tracked_func_cycles: 0, + }); + } + + fn end_iteration(&mut self, timestamp: u64) { + if let Some(iter_state) = self.current_iter.take() { + self.completed_iters.push((iter_state, timestamp)); + } + self.in_iteration = false; + } +} + +pub fn factory( + shared: &Shared, + config: serde_json::Value, + bus_rx: BusReader, +) -> Box { + let marker_func = config + .get("marker_func") + .and_then(|v| v.as_str()) + .unwrap_or("syscall") + .to_string(); + let tracked_func = config + .get("tracked_func") + .and_then(|v| v.as_str()) + .unwrap_or("run_ksoftirqd") + .to_string(); + let csv_path = config + .get("path") + .and_then(|v| v.as_str()) + .unwrap_or("trace.iteration_breakdown.csv") + .to_string(); + Box::new(IterationBreakdownReceiver::new( + bus_rx, + shared.symbol_index.clone(), + marker_func, + tracked_func, + csv_path, + )) +} + +crate::register_receiver!("iteration_breakdown", factory); + +impl AbstractReceiver for IterationBreakdownReceiver { + fn bus_rx(&mut self) -> &mut BusReader { + &mut self.receiver.bus_rx + } + + fn _bump_checksum(&mut self) { + self.receiver.checksum += 1; + } + + fn _receive_entry(&mut self, entry: Entry) { + match entry { + Entry::Instruction { .. } => {} + Entry::Event { + timestamp, + ref kind, + } => { + // 1. Feed to stack unwinder + let update = self.unwinder.step(&entry); + + // 2. Check for marker function exit + if let Some(ref upd) = update { + for frame in &upd.frames_closed { + if frame.symbol.name == self.marker_func { + // Account cycles up to this point before changing iteration state + self.update_prv_cycles(timestamp); + self.prev_timestamp = timestamp; + + self.marker_exit_count += 1; + if self.marker_exit_count % 2 == 1 { + // Odd exit = iteration start + self.start_iteration(timestamp); + } else { + // Even exit = iteration end + self.end_iteration(timestamp); + } + // Only handle one marker per event + break; + } + } + } + + // 3. Track target function entry/exit + if self.in_iteration { + if let Some(ref upd) = update { + if let Some(ref frame) = upd.frames_opened { + if frame.symbol.name == self.tracked_func { + self.in_tracked_func = true; + self.tracked_func_entry_ts = timestamp; + } + } + for frame in &upd.frames_closed { + if frame.symbol.name == self.tracked_func && self.in_tracked_func { + self.in_tracked_func = false; + let cycles = timestamp.saturating_sub(self.tracked_func_entry_ts); + if let Some(ref mut iter_state) = self.current_iter { + iter_state.tracked_func_count += 1; + iter_state.tracked_func_cycles += cycles; + } + } + } + } + } + + // 4. Privilege-level cycle accounting + match kind { + EventKind::SyncStart { + start_prv, + start_ctx: _, + .. + } => { + self.curr_prv = start_prv.clone(); + self.prev_timestamp = timestamp; + } + EventKind::Trap { prv_arc, .. } => { + self.update_prv_cycles(timestamp); + self.curr_prv = prv_arc.1; + self.prev_timestamp = timestamp; + } + _ => { + self.update_prv_cycles(timestamp); + self.prev_timestamp = timestamp; + } + } + } + } + } + + fn _flush(&mut self) { + if self.marker_exit_count == 0 { + warn!( + "iteration_breakdown: no exits of marker function '{}' detected", + self.marker_func + ); + } + if self.in_iteration { + warn!("iteration_breakdown: discarding incomplete iteration (odd number of marker exits: {})", self.marker_exit_count); + } + + // Write CSV + writeln!( + self.writer, + "iter,total_cycles,user_cycles,supervisor_cycles,machine_cycles,{}_count,{}_cycles,{}_avg_cycles", + self.tracked_func, self.tracked_func, self.tracked_func + ) + .unwrap(); + for (i, (state, end_ts)) in self.completed_iters.iter().enumerate() { + let total_cycles = end_ts - state.start_ts; + let avg_cycles = if state.tracked_func_count > 0 { + state.tracked_func_cycles as f64 / state.tracked_func_count as f64 + } else { + 0.0 + }; + writeln!( + self.writer, + "{},{},{},{},{},{},{},{:.0}", + i, + total_cycles, + state.user_cycles, + state.supervisor_cycles, + state.machine_cycles, + state.tracked_func_count, + state.tracked_func_cycles, + avg_cycles + ) + .unwrap(); + } + self.writer.flush().unwrap(); + + println!("--------------------------------"); + println!( + "Iteration breakdown: {} iterations completed", + self.completed_iters.len() + ); + if !self.completed_iters.is_empty() { + let totals: Vec = self + .completed_iters + .iter() + .map(|(s, e)| e - s.start_ts) + .collect(); + let min = totals.iter().min().unwrap(); + let max = totals.iter().max().unwrap(); + let sum: u64 = totals.iter().sum(); + let mean = sum as f64 / totals.len() as f64; + println!( + " Total cycles: min={}, max={}, mean={:.0}", + min, max, mean + ); + } + println!("--------------------------------"); + } +} diff --git a/src/receivers/emulation/abstract_emulator.rs b/src/receivers/emulation/abstract_emulator.rs new file mode 100644 index 0000000..e6548da --- /dev/null +++ b/src/receivers/emulation/abstract_emulator.rs @@ -0,0 +1,18 @@ +use crate::backend::event::{Entry, EventKind}; + +pub trait AbstractEmulator: Send + 'static { + fn push_event(&mut self, entry: Entry); + fn flush(&mut self); + +} + +pub trait AbstractEmulatedAnalyzer: Send + 'static { + fn push_emulated_event(&mut self, event: EmulationResult); + fn flush(&mut self); +} + +pub struct EmulationResult { + pub reference_delta: u64, + pub emulated_delta: u64, + pub event: EventKind, +} \ No newline at end of file diff --git a/src/receivers/emulation/bb_analyzer.rs b/src/receivers/emulation/bb_analyzer.rs new file mode 100644 index 0000000..7538677 --- /dev/null +++ b/src/receivers/emulation/bb_analyzer.rs @@ -0,0 +1,65 @@ +use crate::receivers::emulation::abstract_emulator::{AbstractEmulatedAnalyzer, EmulationResult}; +use std::fs::File; +use std::io::{BufWriter, Write}; + +pub struct BBAnalyzer { + writer: Option>, + total_abs_error: u64, + total_ref_time: u64, + event_count: u64, + name: String, +} + +impl BBAnalyzer { + pub fn new(name: String, path: Option, dump_csv: bool) -> Self { + let writer = if dump_csv { + path.as_ref().map(|p| { + let mut w = BufWriter::new(File::create(p).unwrap()); + w.write_all(b"reference_delta,emulated_delta,event\n").unwrap(); + w + }) + } else { + None + }; + Self { + writer, + total_abs_error: 0, + total_ref_time: 0, + event_count: 0, + name, + } + } +} + +impl AbstractEmulatedAnalyzer for BBAnalyzer { + fn push_emulated_event(&mut self, event: EmulationResult) { + let ref_d = event.reference_delta; + let emu_d = event.emulated_delta; + self.total_abs_error += ref_d.abs_diff(emu_d); + self.total_ref_time += ref_d; + self.event_count += 1; + + if let Some(ref mut writer) = self.writer { + writer + .write_all( + format!( + "{},{},{}\n", + ref_d, + emu_d, + event.event.to_csv_string() + ) + .as_bytes(), + ) + .unwrap(); + } + } + + fn flush(&mut self) { + if let Some(ref mut writer) = self.writer { + writer.flush().unwrap(); + } + + let weighted_error = self.total_abs_error as f64 / self.total_ref_time as f64; + println!("BB Emulation Error ({}): Weighted Error {:.4}%", self.name, weighted_error * 100.0); + } +} diff --git a/src/receivers/emulation/cyc_func_emulation_receiver.rs b/src/receivers/emulation/cyc_func_emulation_receiver.rs index 1bd01c5..1c85ecb 100644 --- a/src/receivers/emulation/cyc_func_emulation_receiver.rs +++ b/src/receivers/emulation/cyc_func_emulation_receiver.rs @@ -60,7 +60,7 @@ pub fn factory( Box::new(CycFuncEmulationReceiver::new(bus_rx, Arc::clone(&_shared.symbol_index), path, lim_tnt)) } -crate::register_receiver!("cyc_func_emulation", factory); +crate::register_receiver!("cyc_func_emulation_old", factory); impl AbstractReceiver for CycFuncEmulationReceiver { fn bus_rx(&mut self) -> &mut BusReader { diff --git a/src/receivers/emulation/emulation_receivers.rs b/src/receivers/emulation/emulation_receivers.rs new file mode 100644 index 0000000..5f2b392 --- /dev/null +++ b/src/receivers/emulation/emulation_receivers.rs @@ -0,0 +1,109 @@ +use crate::backend::event::Entry; +use crate::receivers::abstract_receiver::{AbstractReceiver, BusReceiver, Shared}; +use bus::BusReader; +use crate::receivers::emulation::abstract_emulator::AbstractEmulator; +use crate::receivers::emulation::bb_analyzer::BBAnalyzer; +use crate::receivers::emulation::func_analyzer::FuncAnalyzer; +use std::sync::Arc; +use crate::receivers::emulation::tnt_cyc_nret_emulator::TNTCycNRETEmulator; +use crate::receivers::emulation::tnt_cyc_retcompressed_emulator::TNTCycRETCompressedEmulator; +use crate::receivers::emulation::tc_emulator::TCEmulator; + +// Generic receiver that wraps any AbstractEmulator +pub struct EmulationReceiver { + receiver: BusReceiver, + emulator: Box, +} + +impl EmulationReceiver { + pub fn new(bus_rx: BusReader, name: String, emulator: Box) -> Self { + Self { + receiver: BusReceiver { name, bus_rx, checksum: 0 }, + emulator, + } + } +} + +impl AbstractReceiver for EmulationReceiver { + fn bus_rx(&mut self) -> &mut BusReader { &mut self.receiver.bus_rx } + fn _bump_checksum(&mut self) { self.receiver.checksum += 1; } + fn _receive_entry(&mut self, entry: Entry) { self.emulator.push_event(entry); } + fn _flush(&mut self) { self.emulator.flush(); } +} + +// Helper to parse common config fields +fn parse_common(config: &serde_json::Value) -> (Option, bool) { + let path = config.get("path").and_then(|v| v.as_str()).map(|s| s.to_string()); + let dump_csv = config.get("dump_csv").and_then(|v| v.as_bool()).unwrap_or(false); + (path, dump_csv) +} + +// --- Factories --- + +pub fn tnt_cyc_nret_bb_emulation_factory( + _shared: &Shared, config: serde_json::Value, bus_rx: BusReader, +) -> Box { + let (path, dump_csv) = parse_common(&config); + let lim_tnt = config.get("lim_tnt").and_then(|v| v.as_u64()).unwrap_or(6); + let name = format!("tnt_cyc_nret_bb_emulation_{}", lim_tnt); + let analyzer = Box::new(BBAnalyzer::new(name.clone(), path, dump_csv)); + Box::new(EmulationReceiver::new(bus_rx, name, Box::new(TNTCycNRETEmulator::new(analyzer, lim_tnt)))) +} +crate::register_receiver!("tnt_cyc_nret_bb_emulation", tnt_cyc_nret_bb_emulation_factory); + +pub fn tnt_cyc_retcompressed_bb_emulation_factory( + _shared: &Shared, config: serde_json::Value, bus_rx: BusReader, +) -> Box { + let (path, dump_csv) = parse_common(&config); + let lim_tnt = config.get("lim_tnt").and_then(|v| v.as_u64()).unwrap_or(6); + let name = format!("tnt_cyc_retcompressed_bb_emulation_{}", lim_tnt); + let analyzer = Box::new(BBAnalyzer::new(name.clone(), path, dump_csv)); + Box::new(EmulationReceiver::new(bus_rx, name, Box::new(TNTCycRETCompressedEmulator::new(analyzer, lim_tnt)))) +} +crate::register_receiver!("tnt_cyc_retcompressed_bb_emulation", tnt_cyc_retcompressed_bb_emulation_factory); + +pub fn tc_bb_emulation_factory( + _shared: &Shared, config: serde_json::Value, bus_rx: BusReader, +) -> Box { + let (path, dump_csv) = parse_common(&config); + let interval = config.get("interval").and_then(|v| v.as_u64()).unwrap_or(1000000); + let name = format!("tc_bb_emulation_{}", interval); + let analyzer = Box::new(BBAnalyzer::new(name.clone(), path, dump_csv)); + Box::new(EmulationReceiver::new(bus_rx, name, Box::new(TCEmulator::new(analyzer, interval)))) +} +crate::register_receiver!("tc_bb_emulation", tc_bb_emulation_factory); + +// --- Func-level factories --- + +pub fn tnt_cyc_nret_func_emulation_factory( + shared: &Shared, config: serde_json::Value, bus_rx: BusReader, +) -> Box { + let (path, dump_csv) = parse_common(&config); + let lim_tnt = config.get("lim_tnt").and_then(|v| v.as_u64()).unwrap_or(6); + let name = format!("tnt_cyc_nret_func_emulation_{}", lim_tnt); + let analyzer = Box::new(FuncAnalyzer::new(name.clone(), path, dump_csv, Arc::clone(&shared.symbol_index))); + Box::new(EmulationReceiver::new(bus_rx, name, Box::new(TNTCycNRETEmulator::new(analyzer, lim_tnt)))) +} +crate::register_receiver!("tnt_cyc_nret_func_emulation", tnt_cyc_nret_func_emulation_factory); + +pub fn tnt_cyc_retcompressed_func_emulation_factory( + shared: &Shared, config: serde_json::Value, bus_rx: BusReader, +) -> Box { + let (path, dump_csv) = parse_common(&config); + let lim_tnt = config.get("lim_tnt").and_then(|v| v.as_u64()).unwrap_or(6); + let name = format!("tnt_cyc_retcompressed_func_emulation_{}", lim_tnt); + let analyzer = Box::new(FuncAnalyzer::new(name.clone(), path, dump_csv, Arc::clone(&shared.symbol_index))); + Box::new(EmulationReceiver::new(bus_rx, name, Box::new(TNTCycRETCompressedEmulator::new(analyzer, lim_tnt)))) +} +crate::register_receiver!("tnt_cyc_retcompressed_func_emulation", tnt_cyc_retcompressed_func_emulation_factory); + +pub fn tc_func_emulation_factory( + shared: &Shared, config: serde_json::Value, bus_rx: BusReader, +) -> Box { + let (path, dump_csv) = parse_common(&config); + let interval = config.get("interval").and_then(|v| v.as_u64()).unwrap_or(1000000); + let name = format!("tc_func_emulation_{}", interval); + let analyzer = Box::new(FuncAnalyzer::new(name.clone(), path, dump_csv, Arc::clone(&shared.symbol_index))); + Box::new(EmulationReceiver::new(bus_rx, name, Box::new(TCEmulator::new(analyzer, interval)))) +} +crate::register_receiver!("tc_func_emulation", tc_func_emulation_factory); diff --git a/src/receivers/emulation/func_analyzer.rs b/src/receivers/emulation/func_analyzer.rs new file mode 100644 index 0000000..61284b4 --- /dev/null +++ b/src/receivers/emulation/func_analyzer.rs @@ -0,0 +1,102 @@ +use crate::receivers::emulation::abstract_emulator::{AbstractEmulatedAnalyzer, EmulationResult}; +use std::fs::File; +use std::io::{BufWriter, Write}; +use crate::receivers::stack_unwinder::StackUnwinder; +use crate::common::symbol_index::SymbolIndex; +use std::sync::Arc; +use crate::backend::event::Entry; + +pub struct FuncAnalyzer { + writer: Option>, + total_abs_error: u64, + total_ref_time: u64, + ref_time_stack: Vec, + emu_time_stack: Vec, + unwinder: StackUnwinder, + event_count: u64, + name: String, +} + +impl FuncAnalyzer { + pub fn new(name: String, path: Option, dump_csv: bool, symbols: Arc) -> Self { + let writer = if dump_csv { + path.as_ref().map(|p| { + let mut w = BufWriter::new(File::create(p).unwrap()); + w.write_all(b"reference_delta,emulated_delta,event\n").unwrap(); + w + }) + } else { + None + }; + Self { + writer, + total_abs_error: 0, + total_ref_time: 0, + ref_time_stack: Vec::new(), + emu_time_stack: Vec::new(), + unwinder: StackUnwinder::new(symbols).expect("init unwinder"), + event_count: 0, + name, + } + } +} + +impl AbstractEmulatedAnalyzer for FuncAnalyzer { + fn push_emulated_event(&mut self, event: EmulationResult) { + // first, always add the reference time to the head value of ref_time_stack + if let Some(top) = self.ref_time_stack.last_mut() { + *top += event.reference_delta; + } + if let Some(top) = self.emu_time_stack.last_mut() { + *top += event.emulated_delta; + } + + // then, ask the stack unwinder, where are we? + if let Some(update) = self.unwinder.step(&Entry::Event { timestamp: 0, kind: event.event.clone() }) { + for frame in update.frames_closed { + let ref_time = self.ref_time_stack.pop().unwrap(); + let emu_time = self.emu_time_stack.pop().unwrap(); + let delta_time = ref_time.abs_diff(emu_time); + self.total_abs_error += delta_time; + self.total_ref_time += ref_time; + self.event_count += 1; + if let Some(ref mut writer) = self.writer { + writer.write_all(format!("{},{},{}\n", ref_time, emu_time, frame.symbol.name).as_bytes()).unwrap(); + } + } + if let Some(_) = update.frames_opened { + self.ref_time_stack.push(0); + self.emu_time_stack.push(0); + } + } + + // let ref_d = event.reference_delta; + // let emu_d = event.emulated_delta; + // self.total_abs_error += ref_d.abs_diff(emu_d); + // self.total_ref_time += ref_d; + // self.event_count += 1; + + // if let Some(ref mut writer) = self.writer { + // writer + // .write_all( + // format!( + // "{},{},{}\n", + // ref_d, + // emu_d, + // event.event.to_csv_string() + // ) + // .as_bytes(), + // ) + // .unwrap(); + // } + } + + fn flush(&mut self) { + if let Some(ref mut writer) = self.writer { + writer.flush().unwrap(); + } + + let weighted_error = self.total_abs_error as f64 / self.total_ref_time as f64; + println!("Func Emulation Error ({}): Weighted Error {:.4}%", self.name, weighted_error * 100.0); + } +} diff --git a/src/receivers/emulation/mod.rs b/src/receivers/emulation/mod.rs new file mode 100644 index 0000000..6f7d69b --- /dev/null +++ b/src/receivers/emulation/mod.rs @@ -0,0 +1,21 @@ +#[path = "abstract_emulator.rs"] +pub mod abstract_emulator; + +#[path = "emulation_receivers.rs"] +pub mod emulation_receivers; + +#[path = "bb_analyzer.rs"] +pub mod bb_analyzer; +#[path = "func_analyzer.rs"] +pub mod func_analyzer; +#[path = "tnt_cyc_nret_emulator.rs"] +pub mod tnt_cyc_nret_emulator; +#[path = "tnt_cyc_retcompressed_emulator.rs"] +pub mod tnt_cyc_retcompressed_emulator; +#[path = "tc_emulator.rs"] +pub mod tc_emulator; + +#[path = "cyc_func_emulation_receiver.rs"] +pub mod cyc_func_emulation_receiver; +#[path = "reference_func_receiver.rs"] +pub mod reference_func_receiver; \ No newline at end of file diff --git a/src/receivers/emulation/reference_func_receiver.rs b/src/receivers/emulation/reference_func_receiver.rs index 98e0923..dd5aee0 100644 --- a/src/receivers/emulation/reference_func_receiver.rs +++ b/src/receivers/emulation/reference_func_receiver.rs @@ -48,7 +48,7 @@ pub fn factory( Box::new(ReferenceFuncReceiver::new(bus_rx, Arc::clone(&_shared.symbol_index), path)) } -crate::register_receiver!("reference_func", factory); +crate::register_receiver!("reference_func_old", factory); impl AbstractReceiver for ReferenceFuncReceiver { fn bus_rx(&mut self) -> &mut BusReader { diff --git a/src/receivers/emulation/tc_emulator.rs b/src/receivers/emulation/tc_emulator.rs new file mode 100644 index 0000000..93d9706 --- /dev/null +++ b/src/receivers/emulation/tc_emulator.rs @@ -0,0 +1,79 @@ +use crate::backend::event::{Entry, EventKind}; +use crate::receivers::emulation::abstract_emulator::{AbstractEmulatedAnalyzer, AbstractEmulator, EmulationResult}; + +pub struct TCEmulator { + event_staging: Vec<(u64, EventKind)>, + analyzer: Box, + curr_tc: u64, + curr_timestamp: u64, + interval: u64, +} + +impl TCEmulator { + pub fn new(analyzer: Box, interval: u64) -> Self { + Self { + event_staging: Vec::new(), + analyzer, + curr_tc: 0, + curr_timestamp: 0, + interval, + } + } +} + +impl AbstractEmulator for TCEmulator { + fn push_event(&mut self, entry: Entry) { + match entry { + Entry::Event { timestamp, kind: kind @ EventKind::SyncStart { .. } } => { + self.curr_tc = timestamp / self.interval; // initialize the current TC + self.curr_timestamp = timestamp; + self.analyzer.push_emulated_event(EmulationResult { + reference_delta: 0, + emulated_delta: 0, + event: kind, + }); + } + Entry::Event { timestamp, kind } => { + if timestamp / self.interval != self.curr_tc && !self.event_staging.is_empty() { + // smear the timestamps distributing across all events staged, excluding the current event + let next_tc = timestamp / self.interval; + let slack = (next_tc - self.curr_tc) * self.interval; + let num_events = self.event_staging.len() as u64; + let delta_tc = slack / num_events; + + self.curr_tc = next_tc; + + if num_events > 0 { + // the last events gets the remainder as well + let (last_event_timestamp, last_event) = self.event_staging.pop().unwrap(); + + for (event_timestamp, event) in self.event_staging.iter() { + self.analyzer.push_emulated_event(EmulationResult { + reference_delta: event_timestamp - self.curr_timestamp, + emulated_delta: delta_tc, + event: event.clone(), + }); + self.curr_timestamp = *event_timestamp; + } + + // write the last event + self.analyzer.push_emulated_event(EmulationResult { + reference_delta: last_event_timestamp - self.curr_timestamp, + emulated_delta: delta_tc + slack % num_events, + event: last_event, + }); + self.curr_timestamp = last_event_timestamp; + self.event_staging.clear(); + } + } + self.event_staging.push((timestamp, kind.clone())); + } + _ => {} + } + } + + fn flush(&mut self) { + self.event_staging.clear(); + self.analyzer.flush(); + } +} \ No newline at end of file diff --git a/src/receivers/emulation/tnt_cyc_nret_emulator.rs b/src/receivers/emulation/tnt_cyc_nret_emulator.rs new file mode 100644 index 0000000..41663a9 --- /dev/null +++ b/src/receivers/emulation/tnt_cyc_nret_emulator.rs @@ -0,0 +1,98 @@ +use crate::backend::event::{Entry, EventKind}; +use crate::receivers::emulation::abstract_emulator::{AbstractEmulatedAnalyzer, AbstractEmulator, EmulationResult}; + +// Emulates a TNT based encoder, emitting CYC packets +// It never compresses RET packets ever +pub struct TNTCycNRETEmulator { + event_staging: Vec<(u64, EventKind)>, + lim_tnt: u64, + n_tnt: u64, + curr_cyc: u64, + analyzer: Box, +} + +impl TNTCycNRETEmulator { + pub fn new(analyzer: Box, lim_tnt: u64) -> Self { + Self { + event_staging: Vec::new(), + analyzer, + lim_tnt: lim_tnt, + n_tnt: 0, + curr_cyc: 0, + } + } +} + +impl AbstractEmulator for TNTCycNRETEmulator { + fn push_event(&mut self, entry: Entry) { + match entry { + Entry::Event { timestamp, kind } => { + match kind { + // first, always stage the event + EventKind::SyncStart { .. } => { + self.curr_cyc = timestamp; + self.analyzer.push_emulated_event(EmulationResult { + reference_delta: 0, + emulated_delta: 0, + event: kind.clone(), + }); + } + EventKind::TakenBranch { .. } => { + self.n_tnt += 1; + self.event_staging.push((timestamp, kind.clone())); + } + EventKind::NonTakenBranch { .. } => { + self.n_tnt += 1; + self.event_staging.push((timestamp, kind.clone())); + } + _ => { + self.event_staging.push((timestamp, kind.clone())); + } + } + + // then, detect if we should release the events + if self.n_tnt >= self.lim_tnt || matches!(&kind, EventKind::UninferableJump { .. }) || matches!(&kind, EventKind::Trap { .. }) + { + // smear the timestamps distributing across all events staged, excluding the current event + let slack = timestamp - self.curr_cyc; + let num_events = self.event_staging.len() as u64; + let delta_cyc = slack / num_events; + + if num_events > 0 { + // the last events gets the remainder as well + let (last_event_timestamp, last_event) = self.event_staging.pop().unwrap(); + + for (event_timestamp, event) in self.event_staging.iter() { + self.analyzer.push_emulated_event(EmulationResult { + reference_delta: event_timestamp - self.curr_cyc, + emulated_delta: delta_cyc, + event: event.clone(), + }); + self.curr_cyc = *event_timestamp; + } + + // write the last event + self.analyzer.push_emulated_event(EmulationResult { + reference_delta: last_event_timestamp - self.curr_cyc, + emulated_delta: delta_cyc + slack % num_events, + event: last_event.clone(), + }); + self.curr_cyc = last_event_timestamp; + // clear the states + self.event_staging.clear(); + self.n_tnt = 0; + } + + // update the current cycle + self.curr_cyc = timestamp; + } + } + _ => {} + } + } + + fn flush(&mut self) { + self.event_staging.clear(); + self.analyzer.flush(); + } +} diff --git a/src/receivers/emulation/tnt_cyc_retcompressed_emulator.rs b/src/receivers/emulation/tnt_cyc_retcompressed_emulator.rs new file mode 100644 index 0000000..07261bd --- /dev/null +++ b/src/receivers/emulation/tnt_cyc_retcompressed_emulator.rs @@ -0,0 +1,146 @@ +use crate::backend::event::{Entry, EventKind}; +use crate::common::insn_index::InstructionIndex; +use crate::common::prv::Prv; +use crate::receivers::emulation::abstract_emulator::{AbstractEmulatedAnalyzer, AbstractEmulator, EmulationResult}; +use circular_buffer::CircularBuffer; +use std::sync::Arc; + +const STACK_DEPTH: usize = 64; + +// Emulates a TNT based encoder, emitting CYC packets +// It never compresses RET packets ever +pub struct TNTCycRETCompressedEmulator { + event_staging: Vec<(u64, EventKind)>, + lim_tnt: u64, + n_tnt: u64, + curr_cyc: u64, + analyzer: Box, + stack: CircularBuffer, + needs_flush: bool, + num_compressed: u64, +} + +impl TNTCycRETCompressedEmulator { + pub fn new(analyzer: Box, lim_tnt: u64) -> Self { + Self { + event_staging: Vec::new(), + analyzer, + lim_tnt: lim_tnt, + n_tnt: 0, + curr_cyc: 0, + stack: CircularBuffer::::new(), + needs_flush: false, + num_compressed: 0, + } + } +} + +pub fn close_enough(s: u64, b: u64) -> bool { + if s + 2 == b || s + 4 == b { + true + } else { + false + } +} + +impl AbstractEmulator for TNTCycRETCompressedEmulator { + fn push_event(&mut self, entry: Entry) { + match entry { + Entry::Event { timestamp, kind } => { + match kind { + // first, always stage the event + EventKind::SyncStart { .. } => { + self.curr_cyc = timestamp; + self.analyzer.push_emulated_event(EmulationResult { + reference_delta: 0, + emulated_delta: 0, + event: kind, + }); + } + EventKind::TakenBranch { .. } => { + self.n_tnt += 1; + self.event_staging.push((timestamp, kind.clone())); + } + EventKind::NonTakenBranch { .. } => { + self.n_tnt += 1; + self.event_staging.push((timestamp, kind.clone())); + } + EventKind::InferrableJump { arc } => { + self.stack.push_back(arc.0); + self.event_staging.push((timestamp, kind.clone())); + } + EventKind::UninferableJump { arc } => { + self.event_staging.push((timestamp, kind.clone())); + if !self.stack.is_empty() { + let curr_top = *self.stack.nth_back(0).unwrap(); + // if the current top is the same as where we will return to, then we can compress the event + if close_enough(curr_top, arc.1) { + self.stack.pop_back(); + self.n_tnt += 1; + self.num_compressed += 1; + } else { + // inform a flush + self.needs_flush = true; + } + } + } + EventKind::Trap { .. } => { + self.event_staging.push((timestamp, kind.clone())); + self.needs_flush = true; // unconditionally flush on trap + } + _ => { + self.event_staging.push((timestamp, kind)); + } + } + + // then, detect if we should release the events + if self.n_tnt >= self.lim_tnt || self.needs_flush + { + // smear the timestamps distributing across all events staged, excluding the current event + let slack = timestamp - self.curr_cyc; + let num_events = self.event_staging.len() as u64; + let delta_cyc = slack / num_events; + + if num_events > 0 { + // the last events gets the remainder as well + let (last_event_timestamp, last_event) = self.event_staging.pop().unwrap(); + + for (event_timestamp, event) in self.event_staging.iter() { + self.analyzer.push_emulated_event(EmulationResult { + reference_delta: event_timestamp - self.curr_cyc, + emulated_delta: delta_cyc, + event: event.clone(), + }); + self.curr_cyc = *event_timestamp; + } + + // write the last event + self.analyzer.push_emulated_event(EmulationResult { + reference_delta: last_event_timestamp - self.curr_cyc, + emulated_delta: delta_cyc + slack % num_events, + event: last_event.clone(), + }); + self.curr_cyc = last_event_timestamp; + // clear the states + self.event_staging.clear(); + self.n_tnt = 0; + } + + // update the current cycle + self.curr_cyc = timestamp; + // reset the needs_flush flag + self.needs_flush = false; + } + } + _ => {} + } + } + + fn flush(&mut self) { + self.event_staging.clear(); + self.analyzer.flush(); + println!("Number of compressed events: {}", self.num_compressed); + } +} + + diff --git a/src/receivers/mod.rs b/src/receivers/mod.rs index 57b0d13..860ae8f 100644 --- a/src/receivers/mod.rs +++ b/src/receivers/mod.rs @@ -11,27 +11,37 @@ pub mod bb_stats_receiver; pub mod path_profile_receiver; #[path = "analysis/prv_breakdown_receiver.rs"] pub mod prv_breakdown_receiver; -#[path = "analysis/speedscope_receiver.rs"] +#[path = "analysis/iteration_breakdown_receiver.rs"] +pub mod iteration_breakdown_receiver; +#[path = "analysis/func_path_receiver.rs"] +pub mod func_path_receiver; + +#[path = "print/speedscope_receiver.rs"] pub mod speedscope_receiver; -#[path = "analysis/stack_txt_receiver.rs"] +#[path = "print/stack_txt_receiver.rs"] pub mod stack_txt_receiver; -// #[path = "analysis/txt_delta_receiver.rs"] -// pub mod txt_delta_receiver; -#[path = "analysis/txt_receiver.rs"] +#[path = "print/txt_delta_receiver.rs"] +pub mod txt_delta_receiver; +#[path = "print/txt_receiver.rs"] pub mod txt_receiver; +#[path = "print/sqlite_receiver.rs"] +pub mod sqlite_receiver; -#[path = "emulation/cyc_bb_emulation_receiver.rs"] -pub mod cyc_bb_emulation_receiver; -#[path = "emulation/tc_bb_emulation_receiver.rs"] -pub mod tc_bb_emulation_receiver; -#[path = "emulation/cyc_func_emulation_receiver.rs"] -pub mod cyc_func_emulation_receiver; +// #[path = "emulation/cyc_bb_emulation_receiver.rs"] +// pub mod cyc_bb_emulation_receiver; +// #[path = "emulation/tc_bb_emulation_receiver.rs"] +// pub mod tc_bb_emulation_receiver; +// #[path = "emulation/cyc_func_emulation_receiver.rs"] +// pub mod cyc_func_emulation_receiver; // pub mod tc_func_emulation_receiver; -#[path = "emulation/reference_bb_receiver.rs"] -pub mod reference_bb_receiver; -#[path = "emulation/reference_func_receiver.rs"] -pub mod reference_func_receiver; +#[path = "emulation/mod.rs"] +pub mod emulation; + +// #[path = "emulation/reference_bb_receiver.rs"] +// pub mod reference_bb_receiver; +// #[path = "emulation/reference_func_receiver.rs"] +// pub mod reference_func_receiver; // TODO: mask off for now until verified again // #[path = "experimental/afdo_receiver.rs"] diff --git a/src/receivers/analysis/speedscope_receiver.rs b/src/receivers/print/speedscope_receiver.rs similarity index 100% rename from src/receivers/analysis/speedscope_receiver.rs rename to src/receivers/print/speedscope_receiver.rs diff --git a/src/receivers/print/sqlite_receiver.rs b/src/receivers/print/sqlite_receiver.rs new file mode 100644 index 0000000..6b6489f --- /dev/null +++ b/src/receivers/print/sqlite_receiver.rs @@ -0,0 +1,193 @@ +use crate::backend::event::{Entry, EventKind, TrapReason}; +use crate::common::prv::Prv; +use crate::receivers::abstract_receiver::{AbstractReceiver, BusReceiver, Shared}; +use bus::BusReader; +use rusqlite::Connection; + +struct EventRow { + timestamp: u64, + event_type: &'static str, + from_addr: u64, + to_addr: u64, + prv: u8, + ctx: u64, +} + +pub struct SqliteReceiver { + receiver: BusReceiver, + conn: Connection, + batch: Vec, + batch_size: usize, + curr_prv: Prv, + curr_ctx: u64, + row_count: u64, +} + +impl SqliteReceiver { + pub fn new(bus_rx: BusReader, db_path: String, batch_size: usize) -> Self { + let conn = Connection::open(&db_path).expect("Failed to open SQLite database"); + conn.execute_batch( + "PRAGMA journal_mode = WAL; + PRAGMA synchronous = NORMAL; + DROP TABLE IF EXISTS events; + CREATE TABLE events ( + id INTEGER PRIMARY KEY, + timestamp INTEGER NOT NULL, + event_type TEXT NOT NULL, + from_addr INTEGER, + to_addr INTEGER, + prv INTEGER, + ctx INTEGER + );", + ) + .expect("Failed to create events table"); + + Self { + receiver: BusReceiver { + name: "sqlite".to_string(), + bus_rx, + checksum: 0, + }, + conn, + batch: Vec::with_capacity(batch_size), + batch_size, + curr_prv: Prv::PrvMachine, + curr_ctx: 0, + row_count: 0, + } + } + + fn flush_batch(&mut self) { + if self.batch.is_empty() { + return; + } + let tx = self.conn.transaction().expect("Failed to begin transaction"); + { + let mut stmt = tx + .prepare_cached( + "INSERT INTO events (timestamp, event_type, from_addr, to_addr, prv, ctx) VALUES (?1, ?2, ?3, ?4, ?5, ?6)", + ) + .expect("Failed to prepare insert statement"); + for row in &self.batch { + stmt.execute(rusqlite::params![ + row.timestamp as i64, + row.event_type, + row.from_addr as i64, + row.to_addr as i64, + row.prv, + row.ctx as i64, + ]) + .expect("Failed to insert row"); + } + } + tx.commit().expect("Failed to commit transaction"); + self.row_count += self.batch.len() as u64; + self.batch.clear(); + } + + fn push_event(&mut self, timestamp: u64, event_type: &'static str, from_addr: u64, to_addr: u64) { + self.batch.push(EventRow { + timestamp, + event_type, + from_addr, + to_addr, + prv: self.curr_prv as u8, + ctx: self.curr_ctx, + }); + if self.batch.len() >= self.batch_size { + self.flush_batch(); + } + } +} + +pub fn factory( + _shared: &Shared, + config: serde_json::Value, + bus_rx: BusReader, +) -> Box { + let db_path = config + .get("path") + .and_then(|v| v.as_str()) + .unwrap_or("trace.db") + .to_string(); + let batch_size = config + .get("batch_size") + .and_then(|v| v.as_u64()) + .unwrap_or(10000) as usize; + Box::new(SqliteReceiver::new(bus_rx, db_path, batch_size)) +} + +crate::register_receiver!("sqlite", factory); + +impl AbstractReceiver for SqliteReceiver { + fn bus_rx(&mut self) -> &mut BusReader { + &mut self.receiver.bus_rx + } + + fn _bump_checksum(&mut self) { + self.receiver.checksum += 1; + } + + fn _receive_entry(&mut self, entry: Entry) { + match entry { + Entry::Instruction { .. } => {} + Entry::Event { timestamp, kind } => match kind { + EventKind::TakenBranch { arc } => { + self.push_event(timestamp, "TB", arc.0, arc.1); + } + EventKind::NonTakenBranch { arc } => { + self.push_event(timestamp, "NTB", arc.0, arc.1); + } + EventKind::InferrableJump { arc } => { + self.push_event(timestamp, "IJ", arc.0, arc.1); + } + EventKind::UninferableJump { arc } => { + self.push_event(timestamp, "UJ", arc.0, arc.1); + } + EventKind::Trap { + reason, + prv_arc, + arc, + ctx, + } => { + let event_type = match reason { + TrapReason::Interrupt => "TRAP_INT", + TrapReason::Exception => "TRAP_EXC", + TrapReason::Return => "TRAP_RET", + }; + self.push_event(timestamp, event_type, arc.0, arc.1); + self.curr_prv = prv_arc.1; + if let Some(c) = ctx { + self.curr_ctx = c; + } + } + EventKind::SyncStart { + start_pc, + start_prv, + start_ctx, + .. + } => { + self.curr_prv = start_prv; + self.curr_ctx = start_ctx; + self.push_event(timestamp, "SYNC_START", start_pc, 0); + } + EventKind::SyncEnd { end_pc } => { + self.push_event(timestamp, "SYNC_END", 0, end_pc); + } + _ => {} + }, + } + } + + fn _flush(&mut self) { + self.flush_batch(); + + // Indices are not created automatically — on large traces it's too slow. + // Create them in Python/sqlite3 when needed, e.g.: + // CREATE INDEX idx_events_event_type ON events(event_type); + + println!("--------------------------------"); + println!("SQLite receiver: {} events written", self.row_count); + println!("--------------------------------"); + } +} diff --git a/src/receivers/analysis/stack_txt_receiver.rs b/src/receivers/print/stack_txt_receiver.rs similarity index 100% rename from src/receivers/analysis/stack_txt_receiver.rs rename to src/receivers/print/stack_txt_receiver.rs diff --git a/src/receivers/analysis/txt_delta_receiver.rs b/src/receivers/print/txt_delta_receiver.rs similarity index 100% rename from src/receivers/analysis/txt_delta_receiver.rs rename to src/receivers/print/txt_delta_receiver.rs diff --git a/src/receivers/analysis/txt_receiver.rs b/src/receivers/print/txt_receiver.rs similarity index 100% rename from src/receivers/analysis/txt_receiver.rs rename to src/receivers/print/txt_receiver.rs