JIT services
JIT is a sysmodule for run-time code generation (allowing for overlapping R-X and RW- views of memory). This was added to retail with [10.0.0+]. This was also supported in sdknso for a number of versions prior.
nnMain just initializes ro:1, then starts hosting the service from the main-thread with max_sessions=1 (threads are not created for service-hosting).
This is intended to only be used by Applications. The service-init in sdknso just uses PrepareForJit at the start, then gets the service.
sdknso CreateJitEnvironment implements the remaining initialization. After some validation, this uses svcCreateCodeMemory (can be called twice). Then #CreateJitEnvironment is used. TransferMemory with an user-specified buffer is created with permissions=None, which is then used with #LoadPlugin. When successful, this lastly uses #GetCodeAddress.
This loads the user-specified NRO into sysmodule-context ("DllPlugin"), and calls various symbols from that NRO. It seems the code writing (in cmd GenerateCode) is done via symbol-calling, allowing the NRO to handle input_buffer->code translation+writing.
jit:u
This is "nn::jitsrv::IJitService".
Cmd | Name |
---|---|
0 | #CreateJitEnvironment |
CreateJitEnvironment
Takes two input u64s, 3 input handles, returns an #IJitEnvironment.
IJitEnvironment
This is "nn::jitsrv::IJitEnvironment".
Cmd | Name |
---|---|
0 | #GenerateCode |
1 | #Control |
1000 | #LoadPlugin |
1001 | #GetCodeAddress |
GenerateCode
Takes an u32, an u64, a #CodeRange, a #CodeRange, a #Struct32, a type-0x5 input buffer, a type-0x6 output buffer, and returns an output s32, a #CodeRange, a #CodeRange.
Control
Takes an input u64, a type-0x5 input buffer, a type-0x6 output buffer, and returns an output s32.
LoadPlugin
Takes an input u64 tmem_size, a TransferMemory handle, two type-0x5 input buffers, no output.
The first buffer contains the NRR, the second buffer contains the NRO.
The tmem is temporarily mapped & cleared, when any errors this will also be done again.
The input NRR is used with RegisterModuleInfo2, then the NRO is used with LoadModule (these are copied into another buffer with the required alignment). Afterwards, various symbol lookup is done with the loaded module.
GetCodeAddress
No input, returns two output u64s which are loaded from state.
CodeRange
This is "nn::jit::CodeRange". This is a 0x10-byte struct. This is 8-byte aligned.
Struct32
This is "nn::jitsrv::Struct32". This is a 0x20-byte struct. This is 8-byte aligned.