From 4a2f2085c961ce5eb0eb5be0a0b252427a1e0384 Mon Sep 17 00:00:00 2001 From: angie Date: Sun, 20 Oct 2024 18:44:48 -0300 Subject: [PATCH] Should be mostly done? --- Cargo.toml | 2 +- src/rs/mapfile.rs | 2 +- src/rs/report.rs | 167 ++++++++++++++++++++++++++-------------------- src/rs/symbol.rs | 17 ++--- 4 files changed, 101 insertions(+), 87 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index bafce44..a11cb8f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,7 +25,7 @@ crate-type = ["cdylib", "staticlib", "rlib"] default = [] python_bindings = ["dep:pyo3"] serde = ["dep:serde"] -objdiff_report = ["dep:objdiff-core"] +objdiff_report = ["dep:objdiff-core", "dep:serde"] [dependencies] regex = "1.10.2" diff --git a/src/rs/mapfile.rs b/src/rs/mapfile.rs index 8983842..3e76727 100644 --- a/src/rs/mapfile.rs +++ b/src/rs/mapfile.rs @@ -466,7 +466,7 @@ impl MapFile { // Calculate size of last symbol of the file let sym = &mut file.symbols[symbols_count - 1]; - if sym.size == 0{ + if sym.size == 0 { let sym_size = file.size - acummulated_size; sym.size = sym_size; } diff --git a/src/rs/report.rs b/src/rs/report.rs index 5f7df35..b9b14e5 100644 --- a/src/rs/report.rs +++ b/src/rs/report.rs @@ -16,43 +16,49 @@ fn do_report(mapfile: &mapfile::MapFile) -> report::Report { for (segment_index, segment) in mapfile.segments_list.iter().enumerate() { for section in &segment.files_list { let section_path = section.filepath.to_string_lossy().to_string(); + let mut new_report_unit = report_from_section(section); if let Some(report_unit) = units.iter_mut().find(|x| x.name == section_path) { - report_unit.measures = measures_from_section(report_unit.measures, section); - report_unit.sections.push(report_item_from_section(section)); - report_unit - .functions - .extend(gather_functions_from_section(section)); + report_unit.measures = + merge_measures(report_unit.measures, new_report_unit.measures); + report_unit.sections.extend(new_report_unit.sections); + report_unit.functions.extend(new_report_unit.functions); } else { - let report_unit = report::ReportUnit { - name: section_path.clone(), - measures: measures_from_section(None, section), - sections: vec![report_item_from_section(section)], - functions: gather_functions_from_section(section), - metadata: Some(report::ReportUnitMetadata { - complete: None, - module_name: Some(segment.name.clone()), - module_id: Some(segment_index as u32), - source_path: Some(section_path), - progress_categories: Vec::new(), // TODO - auto_generated: None, // TODO: What? - }), - }; - - units.push(report_unit); + new_report_unit.metadata = Some(report::ReportUnitMetadata { + complete: None, + module_name: Some(segment.name.clone()), + module_id: Some(segment_index as u32), + source_path: Some(section_path), + progress_categories: Vec::new(), // TODO + auto_generated: None, // TODO: What? + }); + + units.push(new_report_unit); } } } for unit in units.iter_mut() { if let Some(measures) = &mut unit.measures { + if measures.total_code > 0 { + measures.matched_code_percent = + measures.matched_code as f32 / measures.total_code as f32 * 100.0; + } + if measures.total_data > 0 { + measures.matched_data_percent = + measures.matched_data as f32 / measures.total_data as f32 * 100.0; + } + if measures.total_functions > 0 { + measures.matched_functions_percent = + measures.matched_functions as f32 / measures.total_functions as f32 * 100.0; + } + let total = measures.total_code + measures.total_data; if total > 0 { - measures.fuzzy_match_percent = (measures.matched_code + measures.matched_data) as f32 / total as f32 * 100.0; + measures.fuzzy_match_percent = + (measures.matched_code + measures.matched_data) as f32 / total as f32 * 100.0; } } - - // unit.sections // .fuzzy_match_percent } let measures = units.iter().flat_map(|u| u.measures.into_iter()).collect(); @@ -71,56 +77,93 @@ fn do_report(mapfile: &mapfile::MapFile) -> report::Report { report } -fn measures_from_section( - measures_aux: Option, - section: &file::File, -) -> Option { - if section.size == 0 { - return None; - } +fn report_from_section(section: &file::File) -> report::ReportUnit { + let mut measures = report::Measures::default(); + let mut report_item = report_item_from_section(section); + let mut functions = Vec::new(); - let mut measures = measures_aux.unwrap_or_default(); let is_text = matches!(section.section_type.as_str(), ".text" | ".start"); for sym_state in section.symbol_match_state_iter(None) { - let sym_size; - match sym_state { + let mut fuzzy_match_percent = 0.0; + + let sym = match sym_state { file::SymbolDecompState::Decomped(sym) => { - sym_size = sym.size; if is_text { measures.matched_code += sym.size; measures.matched_functions += 1; + fuzzy_match_percent = 100.0; } else { measures.matched_data += sym.size; } - }, - file::SymbolDecompState::Undecomped(sym) => { - sym_size = sym.size; - }, - } + sym + } + file::SymbolDecompState::Undecomped(sym) => sym, + }; if is_text { - measures.total_code += sym_size; + measures.total_code += sym.size; measures.total_functions += 1; + + functions.push(report::ReportItem { + name: sym.name.clone(), + size: sym.size, + fuzzy_match_percent, + metadata: Some(report::ReportItemMetadata { + demangled_name: None, + virtual_address: Some(sym.vram), + }), + }); } else { - measures.total_data += sym_size; + measures.total_data += sym.size; } } - if measures.total_code > 0 { - measures.matched_code_percent = measures.matched_code as f32 / measures.total_code as f32 * 100.0; - } - if measures.total_data > 0 { - measures.matched_data_percent = measures.matched_data as f32 / measures.total_data as f32 * 100.0; - } - if measures.total_functions > 0 { - measures.matched_functions_percent = measures.matched_functions as f32 / measures.total_functions as f32 * 100.0; + if measures.total_code + measures.total_data > 0 { + report_item.fuzzy_match_percent = (measures.matched_code + measures.matched_data) as f32 + / (measures.total_code + measures.total_data) as f32 + * 100.0; } // An unit always contains a singular unit, no more, no less. Right? measures.total_units = 1; - Some(measures) + report::ReportUnit { + name: section.filepath.to_string_lossy().to_string(), + measures: Some(measures), + sections: vec![report_item], + functions, + metadata: None, + } +} + +fn merge_measures( + a: Option, + b: Option, +) -> Option { + match (a, b) { + (None, None) => None, + (None, Some(b)) => Some(b), + (Some(a), None) => Some(a), + (Some(a), Some(b)) => Some(report::Measures { + fuzzy_match_percent: 0.0, + total_code: a.total_code + b.total_code, + matched_code: a.matched_code + b.matched_code, + matched_code_percent: 0.0, + total_data: a.total_data + b.total_data, + matched_data: a.matched_data + b.matched_data, + matched_data_percent: 0.0, + total_functions: a.total_functions + b.total_functions, + matched_functions: a.matched_functions + b.matched_functions, + matched_functions_percent: 0.0, + complete_code: 0, + complete_code_percent: 0.0, + complete_data: 0, + complete_data_percent: 0.0, + total_units: 1, + complete_units: 0, + }), + } } fn report_item_from_section(section: &file::File) -> report::ReportItem { @@ -134,25 +177,3 @@ fn report_item_from_section(section: &file::File) -> report::ReportItem { }), } } - -fn gather_functions_from_section(section: &file::File) -> Vec { - if section.section_type != ".text" && section.section_type != ".start" { - return Vec::new(); - } - - let mut funcs = Vec::new(); - - for sym in §ion.symbols { - funcs.push(report::ReportItem { - name: sym.name.clone(), - size: sym.size, - fuzzy_match_percent: 0.0, // TODO - metadata: Some(report::ReportItemMetadata { - demangled_name: None, - virtual_address: Some(sym.vram), - }), - }); - } - - funcs -} diff --git a/src/rs/symbol.rs b/src/rs/symbol.rs index 12a3026..351bef3 100644 --- a/src/rs/symbol.rs +++ b/src/rs/symbol.rs @@ -31,13 +31,7 @@ pub struct Symbol { } impl Symbol { - pub fn new( - name: String, - vram: u64, - size: u64, - vrom: Option, - align: Option, - ) -> Self { + pub fn new(name: String, vram: u64, size: u64, vrom: Option, align: Option) -> Self { Self { name, vram, @@ -227,12 +221,11 @@ pub(crate) mod python_bindings { #[pyo3(signature=(humanReadable=true))] fn serializeSize(&self, humanReadable: bool) -> PyObject { Python::with_gil(|py| { - if humanReadable { - return format!("0x{:X}", self.size).to_object(py); - } - self.size.to_object(py) + if humanReadable { + return format!("0x{:X}", self.size).to_object(py); } - ) + self.size.to_object(py) + }) } #[pyo3(signature=(humanReadable=true))]