Skip to content

Firmware map

Where the application image's code goes, and how much of it has been looked at. The Architecture page describes how the pieces talk. This page accounts for the whole image, one function at a time, and tracks which parts have been read closely.

All figures on this page come from tools/survey.py, run on the owner's own stock NAV SMEG5.43.A.R2 image and the symbol map SPYSTORE copies off the unit. Figures for the AUDIO_BT build will differ.

Scale

NAV 5.43.A.R2
code symbols (T/W in abs_symbols_base) inside the image 89 351
instructions spanned by those symbols ≈ 7.99 million (31.9 MB)
families (class prefix, or library for free functions) 1 030
functions with at least one bl caller, materialised reference or data pointer found 79 462
functions with none found 9 889 (≈ 625 000 instructions)

Reading every instruction by hand is not feasible, so the working unit is the function. Every function gets a row in the survey. Each subsystem that matters to a patch then gets a close reading, recorded in the coverage ledger below.

What the instruction counts over-state

A symbol map carries no sizes. A function's extent runs to the next symbol, so any unlabelled constant data after a function is counted as its code. That is why a few single functions show hundreds of kilobytes (fnmatch, mxmlSetElement). Treat per-function sizes as upper bounds, and family totals as close but inflated.

Where the code goes

About 35% of the instructions belong to families whose names identify a third-party library. That labelling is inferred from names (sqlite3_*, png_*, FT_*, Q*); no library version has been checked against its upstream source.

layer functions instructions share what it is
Qt 20 736 1 437 421 18.0% Qt middleware (widgets, QWS, graphics)
C_HMI_* 9 957 1 292 224 16.2% HMI applications: one family per app (tuner, BT, media, nav, drive, config, upgrade, climate…)
free functions (unlabelled) 8 159 1 064 426 13.3% C code with no class; includes vendor C modules and unrecognised libraries
C_BCM_* 12 202 894 919 11.2% Business components, the logic behind each HMI app, and their DBUS server/client pairs
C++ standard library 9 638 579 088 7.3% template instantiations
C_GUI_* 2 979 362 951 4.5% the vendor widget toolkit over Qt (lists, coverflow, bezier, …)
V3D 2 684 285 849 3.6% the 3D map renderer
C_I2C_SMART_RADIO 299 139 247 1.7% the radio/audio front-end over I2C
TagLib 1 994 137 794 1.7% media tag parsing
SQLite 184 127 099 1.6% the database engine
com_MM_* 2 583 119 826 1.5% generated DBUS proxies (com/MM/... interfaces)
C_MODULE_* 672 97 969 1.2% hardware owners: C_MODULE_TUNER, C_MODULE_AUDIO, the multi-tuner variants
C_NAV_*, TCartogr, Map, M_MAP_MNG 2 006 184 435 2.3% navigation server, cartography and map management
C_SRV_* 1 210 65 136 0.8% services (C_SRV_AUDIO_SERVER, media, tuner)
C_MGR_* 112 10 170 0.1% C_MGR_SRC (the source scheduler) and C_MGR_BT
everything else ≈ 1.2 M ≈ 15% FreeType, libpng, libjpeg, HarfBuzz, expat, a Bluetooth stack, codecs, and ~900 small vendor families

The layer that decides behaviour is small. C_MGR_SRC is 71 functions and ≈ 7 600 instructions out of eight million. Every AUX patch edits C_MGR_SRC, C_HMI_AUDIO_APP_BASE or C_HMI_MEDIA_APP_BASE.

Producing the inventory

tools/survey.py makes one pass over the image. For every code symbol it records:

  • its family and size;
  • its direct bl callers;
  • its materialised references: lis+addi/ori pairs that build its address. This is how most of this firmware's calls are made (through mtctr/bctrl), and it is exactly what tools/callers.py cannot see. C_MGR_SRC::ExecuteAllocationFirstRound has 0 bl callers and 1 materialised reference, from ExecuteAllocation;
  • pointers to it held in data (vtables, callback tables). C_HMI_MEDIA_APP_BASE::InitApp and C_MGR_SRC::StartUp are reached this way only;
  • the strings whose address it builds, usually its trace text;
  • the vtable slots it occupies. A vtable is the _ZTV symbol: two zero words (offset to top, and typeinfo, since there is no RTTI), then one function pointer per slot.

Besides the per-function table it writes three more:

  • vtables.tsv: every slot of every vtable (class, slot offset, function). NAV 5.43.A.R2: 36 758 slots in 3 103 vtables.
  • virtual_calls.tsv: call sites of the form lwz vptr,0(obj) → lwz rZ,off(vptr) → mtctr rZ → bctrl, with the slot offset each calls: 10 495 on NAV. The object's class is not inferred, so a site is not attributed to one function. StartUp and InitApp still show no direct callers for that reason.
  • globals.tsv: each data symbol, including BSS past the end of the image, with the functions that read and write it through lis rX,hi + a load or store at lo(rX): 3 199 on NAV. C_MGR_SRC::m_Instance has 3 readers and 3 writers.
uv run tools/survey.py ~/Downloads/SMEG_PLUS_UPG/NAV/AppBin/f_BigQuick.bin \
    abs_symbols_base.txt.gz --out ~/smeg-survey

It takes f_BigQuick.bin or an inflated image, and abs_symbols_base.txt.gz from a SPYSTORE dump, gzipped or not. The run takes a few seconds. The output is derived from the vendor's symbol map, so it stays on your machine. Do not commit it; see AGENTS.md.

Reference counts are lower bounds

An address taken from a register computed at run time, reached through a branch table, or built further than 30 instructions from its lis is not counted. Nor is a virtual call whose vtable pointer passes through a stack slot or another register first. A function in unreached.tsv has no reference this scan recognises; that does not prove it is dead. 4 100 of the 9 889 are Qt, where unused library code is expected.

Coverage ledger

How closely each part has been examined, using the evidence tiers from Verification. Read means disassembled or decompiled and followed. Executed means run under the emulator or observed on the car.

area depth where
the whole image: every function, vtable slot, virtual call site and global inventoried by tools/survey.py (executed); not read this page
C_MGR_SRC, the source scheduler: all 71 functions every function read; AddRequest and ChangeToNextSchedulerPosition executed under emulation; the boot restore executed on the car (FM without the AUX patches, AUX with them) The source scheduler, The AUX chain
C_MODULE_AUDIO, the audio module: 273 functions 25 read (the AUX path, lifecycle, event dispatch, mute); 248 inferred from names, strings and a decompile digest The audio module
C_HMI_AUDIO_APP_BASE::IsAUXSRCAvailable read; the patched version executed under emulation and on the car The AUX chain, Patches
C_HMI_SrcMgntBase and every ActivateSource(bool) call site (17) read; the InitApp and handler PrOnly edits executed on the car (boot to AUX) How HMI apps request sources
C_HMI_MEDIA_APP_BASE::HandleAudioAuxInputStatusChnged and its HandleDBUSMessage dispatch read; both executed under emulation, stock and with aux-signal-switch The AUX chain, The AUX signal path
the AUX signal path: detection in the radio driver, Elab_AUDIO_AUX_SIGNAL_STATUS_CHANGED, DBUS forwarding, every app's 0xcc handling read. Whether the detector measures AUX while another source plays is not known The AUX signal path
ring tone names: C_SRV_RING_TOUCH::SetRingFilePath and the name literals read; the in-place name patch executed on a real build (not yet on the car) Ring tones
the System Information version screen: C_BCM_VERSION and the C_HMI_CONFIG pages read Version strings
the update flow: C_BCM_UPGRADE (353), C_HMI_UPGRADE (293), C_HMI_UPG (195) about 30 functions read: plugin loading, the contract check, mount/probe, skin rewrite, result mapping; HandlePrivateMessage skimmed per case; the rest inferred from names. Everything after upgplugin_LaunchUpgrade is outside the image The update flow
the package: container, manifests, contract.dat read; the contract decrypted and re-sealed (executed); packages flash on the car Boot & update chain, Media protection
the *_ctrl.bin manifests, including the CheckType-3 CRC-16 layout and all three value types reproduced from the stock files (executed); upgrade.out's CheckEntryFile and the kernel's ComputeCrc read Boot & update chain
cheat codes and the spy collectors: C_BCM_SPY (109), C_BCM_Cheat_Code, the 25 libcheatcode_* libraries every code's Activate read from its relocations; the collect path read; real -USER captures read with tools/spy_read.py (executed) Cheatcodes & spy
HMI framework: messages, event handler, menus named from symbols, partly read Architecture
everything else inventoried by the survey only this page

When a subsystem is read closely, add a row here with its depth and the page it is written on. Keep the tier honest: a function that is named, or that has a caller, has not been read.