github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/targets/nintendoswitch.s (about)

     1  // For more information on the .nro file format, see:
     2  // https://switchbrew.org/wiki/NRO
     3  
     4  .section .text.jmp, "x"
     5  .global _start
     6  _start:
     7      b start
     8      .word _mod_header - _start
     9      .ascii "HOMEBREW"
    10  
    11      .ascii "NRO0"              // magic
    12      .word 0                    // version (always 0)
    13      .word __bss_start - _start // total NRO file size
    14      .word 0                    // flags (unused)
    15  
    16      // segment headers
    17      .word __text_start - _start
    18      .word __text_size
    19      .word __rodata_start - _start
    20      .word __rodata_size
    21      .word __data_start - _start
    22      .word __data_size
    23      .word __bss_size
    24      .word 0
    25  
    26      // ModuleId (not supported)
    27      . = 0x50; // skip 32 bytes
    28  
    29      .word 0 // DSO Module Offset (unused)
    30      .word 0 // reserved (unused)
    31  
    32  .section .data.mod0
    33      .word 0, 8
    34  
    35  .global _mod_header
    36  _mod_header:
    37      .ascii "MOD0"
    38      .word __dynamic_start - _mod_header
    39      .word __bss_start - _mod_header
    40      .word __bss_end - _mod_header
    41      .word 0, 0 // eh_frame_hdr start/end
    42      .word 0 // runtime-generated module object offset
    43  
    44  .section .text.start, "x"
    45  .global start
    46  start:
    47      // save lr
    48      mov  x7, x30
    49  
    50      // get aslr base
    51      bl   +4
    52      sub  x6, x30, #0x88
    53  
    54      // context ptr and main thread handle
    55      mov  x25, x0
    56      mov  x26, x1
    57  
    58      // Save ASLR Base to use later
    59      mov x0, x6
    60  
    61      adrp x4, _saved_return_address
    62      str  x7, [x4, #:lo12:_saved_return_address]
    63  
    64      adrp x4, _context
    65      str x25, [x4, #:lo12:_context]
    66  
    67      adrp x4, _main_thread
    68      str x26, [x4, #:lo12:_main_thread]
    69  
    70      // store stack pointer
    71      mov  x26, sp
    72      adrp x4, _stack_top
    73      str  x26, [x4, #:lo12:_stack_top]
    74  
    75      // clear .bss
    76      adrp x5, __bss_start
    77      add x5, x5, #:lo12:__bss_start
    78      adrp x6, __bss_end
    79      add x6, x6, #:lo12:__bss_end
    80  
    81  bssloop:
    82      cmp x5, x6
    83      b.eq run
    84      str xzr, [x5]
    85      add x5, x5, 8
    86      b bssloop
    87  
    88  run:
    89      // process .dynamic section
    90      // ASLR base on x0
    91      adrp x1, _DYNAMIC
    92      add  x1, x1, #:lo12:_DYNAMIC
    93      bl   __dynamic_loader
    94  
    95      // call entrypoint
    96      b    main
    97  
    98  .global __nx_exit
    99  .type   __nx_exit, %function
   100  __nx_exit:
   101      // Exit code in x0
   102  
   103      // restore stack pointer
   104      mov sp, x1
   105  
   106      // jump back to loader
   107      br   x2
   108  
   109  .section .data.horizon
   110  .align 8
   111  .global _saved_return_address // Saved return address.
   112                                // This might be different than null when coming from launcher
   113  _saved_return_address:
   114      .dword 0
   115  .global _context // Homebrew Launcher Context
   116                   // This might be different than null when not coming from launcher
   117  _context:
   118      .dword 0
   119  
   120  .global _main_thread
   121  _main_thread:
   122      .dword 0
   123  
   124  .global _stack_top
   125  _stack_top:
   126      .dword 0