Firmware Fn 0x1f95d0 - krcenov/RNS510-Map-Viewer GitHub Wiki

0x1f95d0 — unnamed

Part of Firmware Reversing.

  • File offset: 0x1f95d0
  • VA: 0xf6a872c4 (= 0x1f95d0 + 0xf688dcf4)
  • Status: 🟢 Fully traced (prologue to blr)
  • Real name source: not found in the symbol table under any name searched so far

History

The project's oldest lead: found via a Unicorn-emulator candidate classifier searching for functions reading mg4's id/byte1/ length fields (from a pool of 7,757 real function-prologue candidates). Real, complete, understood function — just no confirmed compiler-assigned name.

Disassembly

0x1f95d0: stwu     r1, -0x40(r1)
0x1f95d4: mflr     r0
0x1f95d8: stw      r21, 0x14(r1)
0x1f95dc: stw      r22, 0x18(r1)
0x1f95e0: stw      r23, 0x1c(r1)
0x1f95e4: stw      r24, 0x20(r1)
0x1f95e8: stw      r25, 0x24(r1)
0x1f95ec: stw      r26, 0x28(r1)
0x1f95f0: stw      r27, 0x2c(r1)
0x1f95f4: stw      r28, 0x30(r1)
0x1f95f8: stw      r29, 0x34(r1)
0x1f95fc: stw      r30, 0x38(r1)
0x1f9600: stw      r31, 0x3c(r1)
0x1f9604: stw      r0, 0x44(r1)
0x1f9608: mr       r29, r3                  ; arg1 = seg_list-shaped record ptr
0x1f960c: mr       r27, r4                  ; arg2 = output param
0x1f9610: lhz      r3, 0(r29)               ; record+0 = "id"
0x1f9614: lbz      r4, 2(r29)               ; record+2 = "byte1"
0x1f9618: li       r26, 0xff
0x1f961c: li       r25, 0
0x1f9620: bl       0x1f6c64
0x1f9624: li       r30, 0
0x1f9628: lwz      r4, 4(r29)               ; record+4 = "length" (4-byte field)
0x1f962c: li       r21, 0
0x1f9630: bl       0x1f70d0
0x1f9634: mr       r28, r3
0x1f9638: lhz      r4, 8(r29)
0x1f963c: bl       0x1f7738
0x1f9640: clrlwi   r9, r28, 0x10
0x1f9644: clrlwi   r0, r3, 0x10
0x1f9648: xori     r9, r9, 0xffff
0x1f964c: xori     r0, r0, 0xffff
0x1f9650: neg      r9, r9
0x1f9654: neg      r0, r0
0x1f9658: srwi     r9, r9, 0x1f
0x1f965c: srwi     r0, r0, 0x1f
0x1f9660: and.     r11, r9, r0
0x1f9664: beq      0x1f9678
0x1f9668: lis      r9, -0x95a
0x1f966c: addi     r9, r9, -0xc48           ; table A base (byte-flag lookup)
0x1f9670: lbzx     r0, r9, r3
0x1f9674: rlwinm   r21, r0, 0x1f, 0x1f, 0x1f  ; extract low bit
0x1f9678: cmpwi    r21, 0
0x1f967c: beq      0x1f9828
0x1f9680: mulli    r0, r3, 0x78             ; index * 0x78 (120-byte stride)
0x1f9684: lis      r9, -0x95b
0x1f9688: addi     r31, r9, 0x7878          ; table B base (0x78-byte records)
0x1f968c: add      r29, r0, r31
0x1f9690: lis      r9, -0x968
0x1f9694: lhz      r3, 4(r29)
0x1f9698: addi     r0, r9, -0x6b4
0x1f969c: mtlr     r0
0x1f96a0: addi     r4, r1, 8
0x1f96a4: blrl                              ; virtual call
0x1f96a8: lbz      r0, 8(r1)
0x1f96ac: cmpwi    r0, 0
0x1f96b0: bne      0x1f96c4
0x1f96b4: lhz      r0, 0x66(r29)
0x1f96b8: andi.    r25, r0, 1
0x1f96bc: beq      0x1f9774
0x1f96c0: lbz      r26, 6(r29)
0x1f96c4: cmpwi    r25, 0
0x1f96c8: beq      0x1f9774
0x1f96cc: mulli    r11, r28, 0x60           ; index * 0x60 (96-byte stride)
0x1f96d0: lis      r9, -0x95b
0x1f96d4: addi     r9, r9, 0x1878           ; table C base
0x1f96d8: add      r11, r11, r9
0x1f96dc: lha      r3, 0x5c(r11)
0x1f96e0: cmpwi    r3, -1
0x1f96e4: beq      0x1f9774
0x1f96e8: lis      r9, -0x95a
0x1f96ec: lis      r11, -0xd8
0x1f96f0: addi     r22, r9, -0xc48
0x1f96f4: addi     r23, r11, 0x1538
0x1f96f8: lis      r24, -0x960
0x1f96fc: lis      r25, -0x960
0x1f9700: mulli    r9, r3, 0x78
0x1f9704: mr       r29, r9
0x1f9708: add      r9, r9, r31
0x1f970c: lhz      r0, 0x66(r9)
0x1f9710: andi.    r11, r0, 1
0x1f9714: beq      0x1f975c
0x1f9718: lbz      r0, 6(r9)
0x1f971c: cmpw     r26, r0
0x1f9720: bne      0x1f975c
0x1f9724: lbzx     r0, r22, r3
0x1f9728: andi.    r11, r0, 2
0x1f972c: bne      0x1f975c
0x1f9730: lis      r3, 0x6a14
0x1f9734: mtlr     r23
0x1f9738: ori      r3, r3, 0x202
0x1f973c: lhz      r0, 4(r9)
0x1f9740: addi     r4, r24, -0x1cf0
0x1f9744: sth      r0, 0(r27)               ; write result to *arg2
0x1f9748: addi     r5, r25, -0x1cc4
0x1f974c: mr       r6, r26
0x1f9750: li       r30, 1
0x1f9754: crclr    cr1eq
0x1f9758: blrl                              ; another virtual call
0x1f975c: add      r9, r29, r31
0x1f9760: lha      r3, 0x74(r9)             ; "next" pointer / chain link
0x1f9764: cmpwi    r3, -1
0x1f9768: beq      0x1f9774
0x1f976c: cmpwi    r30, 0
0x1f9770: beq      0x1f9700                 ; loop: walk the chain
0x1f9774: cmpwi    r30, 0
0x1f9778: bne      0x1f9828
0x1f977c: mr       r3, r28
0x1f9780: bl       0x1fa8d8
0x1f9784: cmpwi    r3, -1
0x1f9788: beq      0x1f97a4

(the function continues to a real blr around 0x1f9858, restoring r21-r31 in the standard way — omitted here for length, same epilogue shape as getId.)

Analysis

Reads id, byte1, and length from arg1 — exactly mg4's already-cracked seg_list record layout (research/ map_compressed_reader.py). Walks 3 different lookup tables:

  1. resolves byte1 (+2) through a byte-flag table (table A), extracting its low bit,
  2. resolves length (+0) through a second cache table (table B, 0x78-byte records),
  3. uses the resolved index to walk a THIRD table (table C, 0x60-byte records) via a -1-terminated linked chain (next pointer at record offset 0x74, 0x1f9760/0x1f9770), testing 2 different flag bits (&1, &2) at each step.

On a match, writes a halfword (record offset 4) into the function's own 2nd argument and calls a formatting/lookup routine tagged with a fixed constant 0x6a140202. Consistent with a name/label or junction- connectivity resolver — byte1 acts as a lookup KEY feeding a multi-table resolution chain, not a standalone boolean read directly off the struct. This refines (does not overturn) the project's already-established "divided-road signal" correlation for byte1: the correlation may be a downstream EFFECT of whatever byte1 indexes into, not a direct flag bit read in isolation.

table C's own base (0xf6a51878 as a VA) resolves — via the recovered load base — to the exact same file offset as a real, independently-confirmed UI button-label table ("PLAY...SEARCHBACK...SEARCHFOR...STOP..."), treated here as a 0x60-byte-stride struct array (name + binary fields per record), not flat padded strings — a real named-item descriptor table.

Caller

Not found. 3 independent methods, full 24MB region, plus a whole-file literal-pointer scan — genuine dead end.