reticulatedpines / magiclantern_simplified

A Git based version of Magic Lantern, for those unwilling or unable to work using Mercurial. The vast majority of branches have been removed, with those thought to be important brought in individually and merged.
GNU General Public License v2.0
147 stars 51 forks source link

Finding Ximr structs should not depend on allocators #16

Open reticulatedpines opened 3 years ago

reticulatedpines commented 3 years ago

Current code assumes stubs / consts can provide a fixed location for Ximr structs. This is true on some cams, but not others. E.g. 200D uses fixed address, R uses a pointer at fixed address to refer to address returned by an allocator.

For the latter cams we are currently dumping the address of the Ximr struct from running cams, which is not ideal - the allocators appear deterministic but this means ROM analysis is not enough to get display working. We should change the code to work with the fixed pointers.

kitor commented 3 years ago

Technical explanation (from Discord, so it won't get lost): On 200D / M50 (non-XCM) cameras, XimrContext (XC) struct seems to be always in static location - no allocators found.

On newer cameras it is part of Ximr Context Maker (XCM) structure. XCM is allocated from permanent memory (Digic 8) or it has a special malloc for video driver (Digic X / verified on R6 only).

Flow is as follows:

Initialize_Renderer calls
    VMIX_InitializeScreen calls
        XCM_New, calls
            _memory_allocator_depending_on_generation
            XCM_Reset

this is saved to a pointer inside VMIX structure - which is always in the known (static) place. On R code is hardcoded to create single XCM, on RP/250D/R6 VMIX_InitializeScreen can create multiple XCMs, but Initialize_Renderer calls it with hardcoded 1 count, so from our PoV it is the same.

As for "where XC is located inside XCM struct": Keep in mind that we have an (code backed) assumtion that there will be always only one XCM containing only one XC. Take a look at XCM_PrintStatus code (this is function behind XCMStatus EvShell command that we used to gather XC address on runtime. Look for print: [Ximr Context] No:%d, Addr:0x%08x, Size:0x%08x, Eanabled:%d\n

Now, on Digic 8 generation (R/RP/250D) address is computed as follows: _note: XCid is always 0 due to a previous assumtion. pXCM + XC_id * 0x31c + 0x10 So first XC starts at XCM + 0x10 -> that's what we need.

On Digic X (R6): pXCM + XC_id * 0x7a + 0x4 Because XC structure is 0x7A0 I believe that XCM + 0x4 is pointer to XC, not XC itself. It may be a bug in code too as 0x7a in computation looks awfully similar to 0x7a0 size, and it would accidentally work due to assumption that there's only one XCM/XC. Not tested on real camera.

Stubs for reference:

R_180
e0701996 VMIX_InitializeScreen 
e00dda5a XCM_New
e053a770 allocatePermanentMemory
e00dd9a8 XCM_Reset
e00de3c6 XCM_PrintStatus
RP_160
e07951c4 Initialize_Renderer
e0254908 VMIX_InitializeScreen
e010ebe0 XCM_New
e0588994 allocatePermanentMemory
e010eb10 XCM_Reset
e010f4be XCM_PrintStatus
R6_120
e0978346 Initialize_Renderer
e025c01e VMIX_InitializeScreen
e0171038 XCM_New
e01709c0 VideoDrvMalloc
e0170f8a XCM_Reset
e0171984 XCM_PrintStatus