Difference between revisions of "JIT services"
Line 3: | Line 3: | ||
nnMain just initializes [[RO_services|ro:1]], then starts hosting the service from the main-thread with max_sessions=1 (threads are not created for service-hosting). | nnMain just initializes [[RO_services|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 | + | This is intended to only be used by Applications. The service-init in sdknso just uses [[Applet_Manager_services#PrepareForJit|PrepareForJit]] at the start, then gets the service. |
+ | |||
+ | sdknso CreateJitEnvironment implements the remaining initialization. After some validation, this uses [[SVC|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. | 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. | ||
Line 12: | Line 14: | ||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
|- | |- | ||
− | ! Cmd || Name | + | ! Cmd || Name |
|- | |- | ||
− | | 0 || | + | | 0 || [[#CreateJitEnvironment]] |
|- | |- | ||
|} | |} | ||
+ | |||
+ | == CreateJitEnvironment == | ||
+ | Takes two input u64s, 3 input handles, returns an [[#IJitEnvironment]]. | ||
= IJitEnvironment = | = IJitEnvironment = | ||
Line 25: | Line 30: | ||
! Cmd || Name | ! Cmd || Name | ||
|- | |- | ||
− | | 0 || GenerateCode | + | | 0 || [[#GenerateCode]] |
|- | |- | ||
− | | 1 || Control | + | | 1 || [[#Control]] |
|- | |- | ||
− | | 1000 || LoadPlugin | + | | 1000 || [[#LoadPlugin]] |
|- | |- | ||
− | | 1001 || GetCodeAddress | + | | 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, a handle, two type-0x5 input buffers, no output. | ||
+ | |||
+ | == 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. |
Revision as of 16:52, 15 April 2020
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, a handle, two type-0x5 input buffers, no output.
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.