Firmware Fn getNodeVidArmMP0 - krcenov/RNS510-Map-Viewer GitHub Wiki
Part of Firmware Reversing.
-
File offset:
0x80c7d4(true prologue start; the naive symbol-table field-4 address,0x80c87c, lands 168 bytes into the function's body) -
VA:
0xf709a4c8(= 0x80c7d4 + 0xf688dcf4) - Status: ๐ข Fully traced
- Real name source: symbol/EH-descriptor table, loose (non-strict) match
Directly relevant to this project's own topology work: the name
combines "Vid" (this project's own vnodeID terminology, README
ยง2.6/ยง3.2), "Arm" (a junction's connected segment), and "MP0" (the
already-cracked tile format).
0x80c7d4: stwu r1, -0x140(r1)
0x80c7d8: mflr r0
0x80c7dc: stw r23, 0x11c(r1)
0x80c7e0: stw r24, 0x120(r1)
0x80c7e4: stw r25, 0x124(r1)
0x80c7e8: stw r26, 0x128(r1)
0x80c7ec: stw r27, 0x12c(r1)
0x80c7f0: stw r28, 0x130(r1)
0x80c7f4: stw r29, 0x134(r1)
0x80c7f8: stw r30, 0x138(r1)
0x80c7fc: stw r31, 0x13c(r1)
0x80c800: stw r0, 0x144(r1)
0x80c804: or. r31, r5, r5 ; arg3 (bitmask?) tested for zero
0x80c808: mr r30, r3 ; arg1 = this
0x80c80c: mr r23, r4 ; arg2
0x80c810: beq 0x80c8f0 ; arg3==0 -> jump into shared partial epilogue
0x80c814: li r11, 0x1f ; loop 31 times
0x80c818: lis r0, -0x1248
0x80c81c: mtctr r11
0x80c820: ori r0, r0, 0x8320
0x80c824: stw r0, 0x90(r1)
0x80c828: addi r9, r1, 0x94
0x80c82c: li r0, 1
0x80c830: stw r0, 0(r9) ; build [1, 2, 4, 8, ...] on the stack
0x80c834: addi r9, r9, 4
0x80c838: slwi r0, r0, 1
0x80c83c: bdnz 0x80c830 ; power-of-2 lookup table, 31 entries
0x80c840: lis r9, -0x8ba
0x80c844: addi r29, r1, 0x90
0x80c848: addi r27, r9, -0x3d34
0x80c84c: addi r28, r1, 0x10
0x80c850: mtlr r27
0x80c854: mr r4, r29
0x80c858: mr r3, r28
0x80c85c: mr r25, r29
0x80c860: mr r24, r28
0x80c864: mr r26, r27
0x80c868: blrl ; virtual call #1
0x80c86c: mr r3, r29
0x80c870: mtlr r27
0x80c874: mr r4, r28 ; <- loop-back target (see 0x80c8d8)
0x80c878: blrl ; virtual call #2
0x80c87c: lis r9, -0x8ba
0x80c880: addi r29, r9, -0x3d64
0x80c884: mr r3, r24
0x80c888: mtlr r26
0x80c88c: mr r4, r25
0x80c890: blrl ; virtual call #3
0x80c894: andi. r0, r31, 1 ; test LOW BIT of arg3
0x80c898: beq 0x80c8b0
0x80c89c: mr r4, r30
0x80c8a0: mtlr r29
0x80c8a4: mr r3, r24
0x80c8a8: blrl ; virtual call #4 -- only if bit set
0x80c8ac: mr r30, r3
0x80c8b0: srawi. r31, r31, 1 ; shift to next bit
0x80c8b4: beq 0x80c8ec ; no more set bits -> fall into epilogue
0x80c8b8: mr r3, r25
0x80c8bc: mtlr r26
0x80c8c0: mr r4, r24
0x80c8c4: <data> 000d0029 ; not a valid instruction -- likely an EH-descriptor table entry
0x80c8c8: <data> 00000008 ; not a valid instruction -- likely an EH-descriptor table entry
0x80c8cc: mr r3, r25
0x80c8d0: <data> 000d0019 ; not a valid instruction -- likely an EH-descriptor table entry
0x80c8d4: <data> 00000070 ; not a valid instruction -- likely an EH-descriptor table entry
0x80c8d8: bne 0x80c874 ; LOOP: back to virtual call #2
0x80c8dc: xor r3, r30, r23
0x80c8e0: lwz r0, 0x144(r1)
0x80c8e4: mtlr r0
0x80c8e8: lwz r23, 0x11c(r1)
0x80c8ec: lwz r24, 0x120(r1) ; <- arg3==0 early-exit joins here
0x80c8f0: lwz r25, 0x124(r1)
0x80c8f4: lwz r26, 0x128(r1)
0x80c8f8: lwz r27, 0x12c(r1)
0x80c8fc: lwz r28, 0x130(r1)
0x80c900: lwz r29, 0x134(r1)
0x80c904: lwz r30, 0x138(r1)
0x80c908: lwz r31, 0x13c(r1)
0x80c90c: addi r1, r1, 0x140
0x80c910: <data> 02190021 ; not a valid instruction -- likely an EH-descriptor table entry
0x80c914: <data> 00000048 ; not a valid instruction -- likely an EH-descriptor table entry
0x80c918: lis r11, -0x8ba ; <- a DIFFERENT function starts here
arg3 (r5) is a bitmask, tested for zero up front โ if zero, execution
jumps straight into the middle of the register-restore sequence at
0x80c8f0 (a real compiler-generated shared partial epilogue entry
point, not a bug). Otherwise: builds a 31-entry power-of-2 lookup table
(1, 2, 4, ... 2^30) on the stack, then walks arg3 bit by bit
(andi./srawi. peeling off the low bit each iteration), calling a
virtual method for each SET bit found, with a real backward branch
(0x80c8d8: bne 0x80c874) closing the loop back to the per-bit
virtual-call site. Consistent with "for each requested arm in this
bitmask, resolve its VID individually."
The exact final blr wasn't pinned down: the words right after
addi r1,r1,0x140 (0x80c910/0x80c914) don't decode as valid
instructions, and a genuinely different function's prologue
(lis r11,-0x8ba at 0x80c918) starts immediately after โ most likely
an EH-descriptor table entry sits between the two functions, same
pattern seen elsewhere in this file. Noted honestly rather than
assumed; doesn't affect the function's traced logic above.
Its own virtual-call targets (computed via lis r9,-0x8ba +
addi ...,-0x3d34 and ...,-0x3d64, both at 0x80c840-0x80c880)
resolve to file offsets 0xbce5d8 and 0xbce5a8. This page
originally, wrongly, called these "within the reliable <9MB range."
They are actually ~12.4MB in, past the confirmed 9MB boundary โ the
same already-known readNodeMP0 limitation
(Firmware-Fn-readNodeMP0), not new
territory. Neither is a valid prologue, no real function start exists
within 3,000 bytes of either, and 0xbce5d8 itself lands on readable
text (a mangled-name fragment, "...iptor__C...") rather than code.