Homebrew ABI: Difference between revisions

m Reverted edits by Qlutoo (talk) to last revision by Misson20000
Undo revision 3459 by SciresM (talk)
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 33: Line 35:


  enum LoaderConfigFlags {
  enum LoaderConfigFlags {
   IsRecognitionMandatory = BIT(0),
   IsMandatory = BIT(0),
  };
  };


=== Loader Config Keys ===
=== Loader Config Keys ===
A loader key can be marked as recognition-mandatory or not recognition-mandatory in its <code>Flags</code> field.
A loader key can be marked as mandatory or not 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.


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.
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 that is presence-mandatory is not found (for example with an outdated loader), use <code>result_code=346 | ((200 + key) << 9);</code>.
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 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]] [RECOGNITION-MANDATORY] [PRESENCE-MANDATORY]
* 0: [[#EndOfList]]: Must be present


* 1: [[#MainThreadHandle]] [RECOGNITION-MANDATORY] [PRESENCE-MANDATORY in some cases]
* 1: [[#MainThreadHandle]]: Must be present


* 2: [[#LoaderReturnAddr]] [RECOGNITION-MANDATORY]
* 2: [[#NextLoadPath]]


* 3: [[#OverrideHeap]] [RECOGNITION-MANDATORY]
* 3: [[#OverrideHeap]]: If present, must not be ignored


* 4: [[#OverrideService]]
* 4: [[#OverrideService]]
Line 60: Line 63:
* 6: [[#SyscallAvailableHint]]
* 6: [[#SyscallAvailableHint]]


* 7: [[#AppletType]] [PRESENCE-MANDATORY in some cases]
* 7: [[#AppletType]]: Must be present


* 8: [[#AppletWorkaround]] [RECOGNITION-MANDATORY]
* 8: [[#AppletWorkaround]]: If present, must not be ignored


* 9: [[#StdioSockets]]
* 9: [[#StdioSockets]]
Line 72: Line 75:


* '''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 81: Line 82:


* '''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.


==== LoaderReturnAddr ====
==== NextLoadPath ====
When the homebrew has finished executing, it shall jump to this address to return to the homebrew menu.
Homebrew menu uses this pointer to write the path of next NRO to load, before returning back to Homebrew loader.


* '''Key:''' 2
* '''Key:''' 2
* '''IsRecognitionMandatory:''' True, because the default behaviour may be unsafe if this key is not handled correctly.
* '''Value[0]:''' Pointer to buffer of size 512. File path should start with "sdmc:/".
* '''IsPresenceMandatory:''' False.
* '''Value[1]:''' Pointer to buffer of size 2048. Contains the argv string.
* '''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 101: Line 97:


* '''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 119: Line 113:


* '''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 129: Line 121:


* '''Key:''' 5
* '''Key:''' 5
* '''IsRecognitionMandatory:''' False.
* '''Value[0]:''' Ignored.
* '''IsPresenceMandatory:''' False.
* '''Value[0]:''' Argc.
* '''Value[1]:''' Argv string pointer.
* '''Value[1]:''' Argv string pointer.
* '''DefaultBehavior:''' Setting (argc == 1, argv[0] == "unknown", argv[1] == NULL), or argv parsed in NSO0 fashion.
* '''DefaultBehavior:''' Setting (argc == 1, argv[0] == "", argv[1] == NULL), or argv parsed in NSO0 fashion.


==== SyscallAvailableHint ====
==== SyscallAvailableHint ====
Line 141: Line 131:


* '''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 151: Line 139:


* '''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 168: Line 154:


* '''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 177: Line 161:


* '''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 191: Line 173:


* '''Key:''' 10
* '''Key:''' 10
* '''IsRecognitionMandatory:''' False.
* '''IsPresenceMandatory:''' False.
* '''Value[0]:''' Process handle.
* '''Value[0]:''' Process handle.
* '''Value[1]:''' Ignored.
* '''Value[1]:''' Ignored.