Line 10: |
Line 10: |
| * Resetting MemoryState | | * Resetting MemoryState |
| * No leftover threads running in the background | | * No leftover threads running in the background |
− |
| |
− | Original LR given to entrypoint should be returned to, X0 contains an error code. If original LR is NULL, svcExitProcess should be used.
| |
| | | |
| === Entrypoint Arguments === | | === Entrypoint Arguments === |
Line 35: |
Line 33: |
| | | |
| enum LoaderConfigFlags { | | enum LoaderConfigFlags { |
− | IsMandatory = BIT(0), | + | IsRecognitionMandatory = BIT(0), |
| }; | | }; |
| | | |
| === Loader Config Keys === | | === Loader Config Keys === |
− | A loader key can be marked as mandatory or not in its <code>Flags</code> field. | + | A loader key can be marked as recognition-mandatory or not recognition-mandatory in its <code>Flags</code> field. |
− | | + | The presence-mandatory field is part of the specification and does not go in the <code>Flags</code> field, but any complying loader must pass all fields specified to be presence-mandatory. |
− | If a key is marked as mandatory it means that the application cannot safely ignore it.
| |
| | | |
− | Thus if said key is not recognized by the application, it should exit with <code>result_code=346 | ((100 + key) << 9);</code>, as the default behaviour may be unsafe.
| + | If a key is marked as recognition-mandatory and is not recognized by the application, the program should jump to [[#LoaderReturnAddr]] with <code>result_code=346 | ((100 + key) << 9);</code>, as the default behaviour may be unsafe. |
| | | |
− | If a key that is required is not found (for example with an outdated loader), use <code>result_code=346 | ((200 + key) << 9);</code>. | + | If a key that is presence-mandatory is not found (for example with an outdated loader), use <code>result_code=346 | ((200 + key) << 9);</code>. |
| | | |
| If there is some error encountered while validating an entry's values, use <code>result_code = 346 | ((300 + key) << 9);</code>. | | If there is some error encountered while validating an entry's values, use <code>result_code = 346 | ((300 + key) << 9);</code>. |
| | | |
− | * 0: [[#EndOfList]]: Must be present | + | * 0: [[#EndOfList]] [RECOGNITION-MANDATORY] [PRESENCE-MANDATORY] |
| | | |
− | * 1: [[#MainThreadHandle]]: Must be present | + | * 1: [[#MainThreadHandle]] [RECOGNITION-MANDATORY] [PRESENCE-MANDATORY in some cases] |
| | | |
− | * 2: [[#NextLoadPath]] | + | * 2: [[#LoaderReturnAddr]] [RECOGNITION-MANDATORY] |
| | | |
− | * 3: [[#OverrideHeap]]: If present, must not be ignored | + | * 3: [[#OverrideHeap]] [RECOGNITION-MANDATORY] |
| | | |
| * 4: [[#OverrideService]] | | * 4: [[#OverrideService]] |
Line 63: |
Line 60: |
| * 6: [[#SyscallAvailableHint]] | | * 6: [[#SyscallAvailableHint]] |
| | | |
− | * 7: [[#AppletType]]: Must be present | + | * 7: [[#AppletType]] [PRESENCE-MANDATORY in some cases] |
| | | |
− | * 8: [[#AppletWorkaround]]: If present, must not be ignored | + | * 8: [[#AppletWorkaround]] [RECOGNITION-MANDATORY] |
| | | |
| * 9: [[#StdioSockets]] | | * 9: [[#StdioSockets]] |
Line 75: |
Line 72: |
| | | |
| * '''Key:''' 0 | | * '''Key:''' 0 |
| + | * '''IsRecognitionMandatory:''' True, because not recognizing this tag would send the loader off the end of the list. |
| + | * '''IsPresenceMandatory:''' True, because the list must be terminated. |
| * '''Value[0]:''' Ignored. | | * '''Value[0]:''' Ignored. |
| * '''Value[1]:''' Ignored. | | * '''Value[1]:''' Ignored. |
Line 82: |
Line 81: |
| | | |
| * '''Key:''' 1 | | * '''Key:''' 1 |
| + | * '''IsRecognitionMandatory:''' True. |
| + | * '''IsPresenceMandatory:''' True if entry function was called with INVALID_HANDLE. |
| * '''Value[0]:''' Handle to the main thread. | | * '''Value[0]:''' Handle to the main thread. |
| * '''Value[1]:''' Ignored. | | * '''Value[1]:''' Ignored. |
| * '''DefaultBehavior:''' Use main thread handle from entry function arguments. | | * '''DefaultBehavior:''' Use main thread handle from entry function arguments. |
| | | |
− | ==== NextLoadPath ==== | + | ==== LoaderReturnAddr ==== |
− | Homebrew menu uses this pointer to write the path of next NRO to load, before returning back to Homebrew loader.
| + | When the homebrew has finished executing, it shall jump to this address to return to the homebrew menu. |
| | | |
| * '''Key:''' 2 | | * '''Key:''' 2 |
− | * '''Value[0]:''' Pointer to buffer of size 512. File path should start with "sdmc:/". | + | * '''IsRecognitionMandatory:''' True, because the default behaviour may be unsafe if this key is not handled correctly. |
− | * '''Value[1]:''' Pointer to buffer of size 2048. Contains the argv string. | + | * '''IsPresenceMandatory:''' False. |
| + | * '''Value[0]:''' Function pointer with type <code>void __noreturn (*)(int result_code);</code> |
| + | * '''Value[1]:''' Ignored. |
| + | * '''DefaultBehavior:''' Returns back to where LR was when the program entered, or exits process using svcExitProcess if LR was NULL. |
| | | |
| ==== OverrideHeap ==== | | ==== OverrideHeap ==== |
Line 97: |
Line 101: |
| | | |
| * '''Key:''' 3 | | * '''Key:''' 3 |
| + | * '''IsRecognitionMandatory:''' True, because the default behaviour may be unsafe if this key is not handled correctly. |
| + | * '''IsPresenceMandatory:''' False. |
| * '''Value[0]:''' Base address of heap. Must be MemoryType 4, 5, or 9 with all reference counts being zero. | | * '''Value[0]:''' Base address of heap. Must be MemoryType 4, 5, or 9 with all reference counts being zero. |
| * '''Value[1]:''' Size of heap. | | * '''Value[1]:''' Size of heap. |
Line 113: |
Line 119: |
| | | |
| * '''Key:''' 4 | | * '''Key:''' 4 |
| + | * '''IsRecognitionMandatory:''' False. |
| + | * '''IsPresenceMandatory:''' False. |
| * '''Value[0]:''' Name of service, same format as for sm. | | * '''Value[0]:''' Name of service, same format as for sm. |
| * '''Value[1]:''' Service handle. | | * '''Value[1]:''' Service handle. |
Line 121: |
Line 129: |
| | | |
| * '''Key:''' 5 | | * '''Key:''' 5 |
− | * '''Value[0]:''' Ignored. | + | * '''IsRecognitionMandatory:''' False. |
| + | * '''IsPresenceMandatory:''' False. |
| + | * '''Value[0]:''' Argc. |
| * '''Value[1]:''' Argv string pointer. | | * '''Value[1]:''' Argv string pointer. |
− | * '''DefaultBehavior:''' Setting (argc == 1, argv[0] == "", argv[1] == NULL), or argv parsed in NSO0 fashion. | + | * '''DefaultBehavior:''' Setting (argc == 1, argv[0] == "unknown", argv[1] == NULL), or argv parsed in NSO0 fashion. |
| | | |
| ==== SyscallAvailableHint ==== | | ==== SyscallAvailableHint ==== |
Line 131: |
Line 141: |
| | | |
| * '''Key:''' 6 | | * '''Key:''' 6 |
| + | * '''IsRecognitionMandatory:''' False. |
| + | * '''IsPresenceMandatory:''' False. |
| * '''Value[0]:''' 64-bit mask for the 0-0x3F SVC range. n:th bit set means SVC is accessible. | | * '''Value[0]:''' 64-bit mask for the 0-0x3F SVC range. n:th bit set means SVC is accessible. |
| * '''Value[1]:''' 64-bit mask for the 0x40-0x7F SVC range. | | * '''Value[1]:''' 64-bit mask for the 0x40-0x7F SVC range. |
Line 139: |
Line 151: |
| | | |
| * '''Key:''' 7 | | * '''Key:''' 7 |
| + | * '''IsRecognitionMandatory:''' False. |
| + | * '''IsPresenceMandatory:''' Application-defined. Depends on whether the application is using any applet services or not. |
| * '''Value[0]:''' AppletType | | * '''Value[0]:''' AppletType |
| * '''Value[1]:''' Ignored. | | * '''Value[1]:''' Ignored. |
Line 154: |
Line 168: |
| | | |
| * '''Key:''' 8 | | * '''Key:''' 8 |
| + | * '''IsRecognitionMandatory:''' True, because the default behaviour (using applet services) is unsafe if this tag is passed. |
| + | * '''IsPresenceMandatory:''' False. |
| * '''Value[0]:''' AppletResourceUserId | | * '''Value[0]:''' AppletResourceUserId |
| * '''Value[1]:''' Ignored. | | * '''Value[1]:''' Ignored. |
Line 161: |
Line 177: |
| | | |
| * '''Key:''' 9 | | * '''Key:''' 9 |
| + | * '''IsRecognitionMandatory:''' False. |
| + | * '''IsPresenceMandatory:''' False. |
| * '''Value[0]:''' First word: stdout file descriptor, second word: stdin file descriptor | | * '''Value[0]:''' First word: stdout file descriptor, second word: stdin file descriptor |
| * '''Value[1]:''' Third word: stderr file descriptor, fourth word: SocketService | | * '''Value[1]:''' Third word: stderr file descriptor, fourth word: SocketService |
Line 173: |
Line 191: |
| | | |
| * '''Key:''' 10 | | * '''Key:''' 10 |
| + | * '''IsRecognitionMandatory:''' False. |
| + | * '''IsPresenceMandatory:''' False. |
| * '''Value[0]:''' Process handle. | | * '''Value[0]:''' Process handle. |
| * '''Value[1]:''' Ignored. | | * '''Value[1]:''' Ignored. |