Difference between revisions of "Homebrew ABI"

From Nintendo Switch Brew
Jump to navigation Jump to search
Line 32: Line 32:
 
* 1: [[#MainThreadHandle]] [MANDATORY]
 
* 1: [[#MainThreadHandle]] [MANDATORY]
  
* 2: [[#OverrideHeap]]
+
* 2: [[#LoaderReturnAddr]] [MANDATORY]
  
* 3: [[#OverrideService]]
+
* 3: [[#OverrideHeap]]
 +
 
 +
* 4: [[#OverrideService]]
 +
 
 +
* 5: [[#Argv]]
  
 
==== EndOfList ====
 
==== EndOfList ====
Line 51: Line 55:
 
* '''Value[0]:''' Handle to the main thread.
 
* '''Value[0]:''' Handle to the main thread.
 
* '''Value[1]:''' Ignored.
 
* '''Value[1]:''' Ignored.
 +
 +
==== LoaderReturnAddr ====
 +
When the homebrew has finished executing, it shall jump to this address to return to the homebrew menu.
 +
 +
* '''Key:''' 1
 +
* '''IsMandatory:''' True
 +
* '''Value[0]:''' Function pointer with type <code>void __noreturn (*)(int result_code);</code>
 +
* '''Value[1]:''' Ignored.
 +
* '''DefaultBehavior:''' Exits process using svcExitProcess.
  
 
==== OverrideHeap ====
 
==== OverrideHeap ====
 
If the NRO loader has reserved some space in the heap for itself, the application must not manipulate the heap.
 
If the NRO loader has reserved some space in the heap for itself, the application must not manipulate the heap.
  
* '''Key:''' 2
+
* '''Key:''' 3
 
* '''IsMandatory:''' False
 
* '''IsMandatory:''' 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.
Line 66: Line 79:
 
Note: For services that authenticate with pid, the app should not attempt re-authentication with an overridden handle.
 
Note: For services that authenticate with pid, the app should not attempt re-authentication with an overridden handle.
  
* '''Key:''' 3
+
* '''Key:''' 4
 
* '''IsMandatory:''' False
 
* '''IsMandatory:''' 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.
 
* '''DefaultBehavior:''' Fetches service from "sm:" named port.
 
* '''DefaultBehavior:''' Fetches service from "sm:" named port.
 +
 +
==== Argv ====
 +
The NRO loader should be able to send argv.
 +
 +
* '''Key:''' 5
 +
* '''IsMandatory:''' False
 +
* '''Value[0]:''' Argc.
 +
* '''Value[1]:''' Argv pointer.
 +
* '''DefaultBehavior:''' Setting (argc == 0, argv[0] == NULL), or argv parsed in NSO0 fashion.

Revision as of 23:39, 5 January 2018

DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT

Entrypoint

Entrypoint is at binary_ptr+0. At this offset, there is a branch instruction that jumps past the NRO0 header. This is for compatibility with NSO0.

Entrypoint Arguments

NSO0: the system executes binary_ptr+0 with X0=NULL, X1=main_thread_handle.

NRO0: the homebrew loader puts X1=0xFFFFFFFFFFFFFFFF [INVALID_HANDLE] and X0=loader_config_ptr.

Loader Config

Loader config allows overriding functionality to workaround limitations in a limited homebrew environment.

It is an array of tuples:

struct LoaderConfig {
  LoaderConfigEntry Entries[];
};

Each entry is key-value pair:

struct LoaderConfigEntry {
  u32 Key;
  u8  IsMandatory;
  u8  Reserved[3];
  u64 Value[2];
};

Loader Config Keys

EndOfList

EndOfList is the final entry in the LoaderConfig.

  • Key: 0
  • IsMandatory: True
  • Value[0]: Ignored.
  • Value[1]: Ignored.

MainThreadHandle

This is the handle to the thread that is executing the entrypoint. Required for mutex to function.

  • Key: 1
  • IsMandatory: True
  • Value[0]: Handle to the main thread.
  • Value[1]: Ignored.

LoaderReturnAddr

When the homebrew has finished executing, it shall jump to this address to return to the homebrew menu.

  • Key: 1
  • IsMandatory: True
  • Value[0]: Function pointer with type void __noreturn (*)(int result_code);
  • Value[1]: Ignored.
  • DefaultBehavior: Exits process using svcExitProcess.

OverrideHeap

If the NRO loader has reserved some space in the heap for itself, the application must not manipulate the heap.

  • Key: 3
  • IsMandatory: False
  • Value[0]: Base address of heap. Must be MemoryType 4, 5, or 9 with all reference counts being zero.
  • Value[1]: Size of heap.
  • DefaultBehavior: Allocates heap using svcSetHeapSize instead.

OverrideService

The NRO loader should be able to steal handles from more priliveged processes. In this case, the homebrew should use this handle instead of the normal one.

Note: For services that authenticate with pid, the app should not attempt re-authentication with an overridden handle.

  • Key: 4
  • IsMandatory: False
  • Value[0]: Name of service, same format as for sm.
  • Value[1]: Service handle.
  • DefaultBehavior: Fetches service from "sm:" named port.

Argv

The NRO loader should be able to send argv.

  • Key: 5
  • IsMandatory: False
  • Value[0]: Argc.
  • Value[1]: Argv pointer.
  • DefaultBehavior: Setting (argc == 0, argv[0] == NULL), or argv parsed in NSO0 fashion.