HOW IT WORKS AND WHY IT ISN’T JUST A PORTED WinOLS - MykeHaunt/Mac-OLS GitHub Wiki
The cornerstone feature of Mac-OLS is its ability to automatically detect maps in raw ECU binary files. These maps represent critical tuning tables—such as ignition timing, fuel injection, torque limits, and turbo control curves—which are encoded as arrays of numeric values. The ability to identify these maps without prior knowledge of the ECU layout (i.e., without Damos/A2L files) requires a combination of heuristic analysis and pattern recognition.
This section describes the core map detection strategies implemented in Mac-OLS.
- Detect 1D (Axis) and 2D (Table) maps.
- Operate on raw binary data, without symbolic information.
- Identify maps based on statistical patterns (monotonicity, regular spacing, float patterns).
- Report offset, dimensions, and data type of each candidate map.
- Minimize false positives and support user validation.
Maps are represented using lightweight Rust structs that store both metadata and raw content:
pub struct Axis1D {
pub offset: usize,
pub length: usize,
pub data: Vec<f32>,
}
pub struct Table2D {
pub offset: usize,
pub rows: usize,
pub cols: usize,
pub data: Vec<f32>,
}
These structures are then serialized to the SwiftUI frontend over a C-ABI bridge for GUI rendering and editing.
The core strategy is based on a sliding window scan with heuristic scoring. Binary files are typically large (several MB), so performance and efficiency are essential.
- Iterate over the file in steps (e.g., 2 or 4 bytes for 16-bit or 32-bit data).
- At each position, read a window of potential map data.
- Example: For 2D detection, a 16×16 window is read as 256 values.
- Attempt to interpret values as
u16
,i16
,f32
, etc., based on context or entropy.
The following heuristics are applied to the window contents:
Heuristic | Description |
---|---|
Monotonicity | For 1D maps, checks if the sequence is strictly increasing/decreasing. |
Low Variance Rows/Cols | For 2D maps, checks for smooth value transitions along each axis. |
Step Uniformity | Axes in ECU maps often have constant or linearly spaced steps (e.g., 500, 1000, 1500 RPM). |
Floating Point Validity | If interpreting data as f32 , validate exponent and mantissa to avoid NaNs or invalid floats. |
Context Clues | Surrounding bytes may have recognizable markers (e.g., map header signatures, padding, DTC tables). |
Each heuristic contributes a score, and candidate regions are accepted only if the cumulative score exceeds a dynamic threshold.
Candidate regions are evaluated for best-fit dimensions:
- For a detected 256-value block, try
(16,16)
,(32,8)
,(8,32)
, etc. - Score each dimension based on continuity, symmetry, and typical ECU layouts.
- Select dimensions with the highest composite score.
Once maps are detected:
- Remove overlaps with higher scoring maps.
- Merge subregions into larger maps if they appear to be connected (e.g., shared axes).
- Normalize and deduplicate maps that appear multiple times with slightly different offsets.
- Synthetic Test Binaries: Generated binaries with known embedded maps (float arrays, int tables).
- Fuzzed Input: Random binary data is used to ensure robustness against false positives.
- Golden Files: ECU binaries with verified WinOLS map locations are used for regression testing.
-
Unit Tests: Individual heuristics (monotonicity, float parsing) are covered with Rust tests using
#[test]
.
The CLI interface allows users to run detection on arbitrary binaries:
ecutil-cli detect myecu.bin
Output includes a JSON or tabular summary of detected maps:
[+] Found 1D Axis at 0x0012A0: 16 elements
[+] Found 2D Table at 0x002B10: 16x16
This output can be piped to other tools or the GUI frontend.
Detected maps are visualized as:
- Hex overlays (color-coded segments over the raw binary).
- 2D table editors (editable grid of numbers).
- 3D surface plots (for high-res tuning visualization).
Planned future extensions will allow:
- User-supplied detection patterns via plugins.
- ML-based map shape recognition.
- Reverse Damos generation from detected map patterns.
Users and developers can tweak detection sensitivity:
-
--min-map-size
: Minimum element count for consideration. -
--data-type
: Force map type (f32
,u16
, etc.). -
--heuristic-threshold
: Set a custom score threshold. -
--allow-overlaps
: Disable overlap filtering.
These are tunable via CLI flags or GUI preferences pane.
Feature | WinOLS | Mac-OLS |
---|---|---|
Heuristic Map Search | ✅ Built-in | ✅ Native Rust |
Damos/A2L Support | ✅ Proprietary | 🚧 Planned Plugin |
Map Shape Inference | ✅ Visual | ✅ Surface View |
Plugin Detection Modules | ❌ Closed | ✅ Dynamic Plugins |
fn detect_axis(data: &[u8], start: usize, len: usize) -> Option<Axis1D> {
let floats = try_parse_f32_sequence(&data[start..start + len * 4])?;
if is_monotonic(&floats) || is_evenly_spaced(&floats) {
Some(Axis1D {
offset: start,
length: len,
data: floats,
})
} else {
None
}
}
Mac-OLS leverages pattern-based heuristics and fast Rust-based scanning to automatically identify tuning maps in raw ECU binaries. The detection system is modular, testable, and extensible—designed for accuracy and performance. Future enhancements will include ML-assisted detection, user-defined rules, and format-specific map profiles.