Skip to content

Firmware Fn filterToggleSeg

Kristiyan edited this page Oct 1, 2026 · 4 revisions

filterToggleSeg

Part of Firmware Reversing.

  • Naive symbol-table address: 0x607074 (VA 0xf6e94d68)
  • True prologue start: 0x606e64 (VA 0xf6e94b58)
  • Status: 🟡* Partially traced — major correction: this is NOT a standalone 108-byte leaf function as earlier documented. Real, CPU-verified (Unicorn emulation, not just static disassembly), valid, meaningful code continues for at least another ~400 bytes past the originally-assumed end at 0x606ed0, through at least 3 more of the same "data blob" anomalies documented on Firmware Reversing, before reaching something that LOOKS like a clean, matching epilogue around 0x606fe0 — which is itself immediately followed by yet another blob and more real code. The true full extent of whatever this really is was not fully bounded.
  • Full mangled name: filterToggleSeg__FP4vseg (a global function, not a class method — __F mangling prefix) — this name may only cover the small entry fragment originally documented, not the much larger body now known to follow it.

Takes a single vseg argument — directly relevant to this project's own segment-attribute work.

The originally-documented entry fragment (still accurate as far as it goes)

0x606e64: stwu     r1, -0x10(r1)
0x606e68: mflr     r0
0x606e6c: stw      r30, 8(r1)
0x606e70: stw      r31, 0xc(r1)
0x606e74: stw      r0, 0x14(r1)
0x606e78: mr       r30, r3                  ; arg1 = this
0x606e7c: lwz      r9, 0xc(r30)
0x606e80: mr       r31, r4                  ; arg2 = requested index
0x606e84: lha      r3, 0x18(r9)
0x606e88: lwz      r0, 0x1c(r9)
0x606e8c: add      r3, r30, r3
0x606e90: mtlr     r0
0x606e94: blrl                              ; virtual call -- returns a count/bound
0x606e98: cmplw    r31, r3                  ; index < count ?
0x606e9c: blt      0x606ebc                 ; out of range -> skip straight to epilogue
0x606ea0: lwz      r9, 0xc(r30)
0x606ea4: <data>    00080029   ; blob #1 (inline, mid-body)
0x606ea8: <data>    00000048
0x606eac: addi     r31, r3, -1
0x606eb0: lwz      r0, 4(r30)               ; array base
0x606eb4: slwi     r3, r31, 2               ; index * 4
0x606eb8: add      r3, r0, r3               ; &array[index]
0x606ebc: lwz      r0, 0x14(r1)
0x606ec0: mtlr     r0
0x606ec4: lwz      r30, 8(r1)
0x606ec8: lwz      r31, 0xc(r1)
0x606ecc: addi     r1, r1, 0x10
0x606ed0: <data>    001f01f9   ; blob #2

Real, coherent bounds-checked array access: calls a virtual method to get a count/bound, compares the caller's requested index against it, and if in range, computes &array[index-1] from a base pointer stored at this+4. This much is genuinely clean and self-contained.

What actually comes next — CPU-verified via Unicorn, not assumed

Tested directly: loaded the real bytes into a Unicorn PPC32 (big-endian) emulator with the ENTIRE 24MB native region mapped from the real file, set r3/r4 (the registers this code reads immediately after blob #2) to real, mapped, realistic pointers, and ran it. Result: 13 real instructions execute cleanly, and the target memory is verifiably, correctly updated — a literal test value (1234) placed in the source record shows up copied into the destination record afterward. This is not garbage execution; it's a real, working 8-byte-record copy:

0x606edc: mr       r31, r3
0x606ee0: mr       r28, r4
0x606ee4: cmpw     r31, r28
0x606ee8: beq      0x606fc8
0x606eec: lwz      r9, 8(r28)
0x606ef0: lwz      r0, 0(r28)
0x606ef4: cmpwi    r9, 0
0x606ef8: stw      r0, 0(r31)               ; copy field 1
0x606efc: stw      r9, 8(r31)               ; copy field 2
0x606f00: beq      0x606f3c

Continuing past 0x606f3c (confirmed valid via the same live run): calls getOffroadDistanceFromRouteToDestination__25CfcTypeRoadClassStatistic (the same real function seen on mv_convert_slot_nr and getSegProperty) with a real index-to-byte-offset computation (slwi r3,r3,2) as part of its arguments — real, meaningful, on-topic logic, not disconnected noise. Then a genuine array-copy loop (0x606f88-0x606fc0: stwx indexed stores, incrementing a cursor by 4 each iteration), ending in mr r3,r31 (return this, a real "return *this"-shaped idiom) and what looks like a clean, correctly-matching epilogue at 0x606fc8- 0x606fe0 (addi r1,r1,0x20) — immediately followed by yet another blob, then more real code (__nw__35CfcAspectGuidanceStatusChangedEventUi, the same guidance-status-changed event construction seen on addSegmentData/ getSegProperty), not chased further.

Net read — a revised understanding

The original "clean 108-byte leaf function" characterization was wrong, or at best radically incomplete — confirmed by actually executing the bytes, not just reading them. The real structure appears to be: one or a few logically-related, much larger real functions, whose compiled layout interleaves real inline data (the same "undecodable" blobs documented centrally) between multiple genuine code segments — each transition point looking, to a linear reader, like "function ends, then garbage, then a new one starts," when the evidence now suggests real control flow likely branches AROUND each blob (not through it) via mechanisms this project hasn't mapped yet. This reframes the central "no locally-visible blr" anomaly: it may not be "functions mysteriously missing their return," so much as "this project's linear, function-at-a-time reading model doesn't match how this compiler actually laid out groups of related functions/call-sites with inline per-site metadata." A genuinely promising, re-opened research direction — see Firmware Reversing.

Callees

Within the originally-documented 108-byte fragment: none (a real, self-contained leaf for that part). Within the much larger body now known to follow: getOffroadDistanceFromRouteToDestination, __nw__35CfcAspectGuidanceStatusChangedEventUi, and at least one more unresolved virtual/indirect call — not exhaustively traced.

Clone this wiki locally