mirror of
https://github.com/switchbrew/libnx.git
synced 2025-06-21 20:42:44 +02:00
191 lines
4.2 KiB
ArmAsm
191 lines
4.2 KiB
ArmAsm
.macro CODE_BEGIN name
|
|
.section .text.\name, "ax", %progbits
|
|
.global \name
|
|
.type \name, %function
|
|
.align 2
|
|
.cfi_startproc
|
|
\name:
|
|
.endm
|
|
|
|
.macro CODE_END
|
|
.cfi_endproc
|
|
.endm
|
|
|
|
// Called by crt0 when the args at the time of entry indicate an exception occured.
|
|
|
|
.weak __libnx_exception_handler
|
|
|
|
.weak __libnx_exception_entry
|
|
CODE_BEGIN __libnx_exception_entry
|
|
cmp x1, #0
|
|
beq __libnx_exception_entry_abort
|
|
|
|
// Abort exception handling when __libnx_exception_handler is not defined.
|
|
adrp x5, :got:__libnx_exception_handler
|
|
ldr x5, [x5, #:got_lo12:__libnx_exception_handler]
|
|
cmp x5, #0
|
|
beq __libnx_exception_entry_abort
|
|
|
|
// Load IsCurrentProcessBeingDebugged.
|
|
|
|
stp x9, x10, [sp, #-16]!
|
|
stp x11, x12, [sp, #-16]!
|
|
stp x13, x14, [sp, #-16]!
|
|
stp x15, x16, [sp, #-16]!
|
|
stp x17, x18, [sp, #-16]!
|
|
stp x19, x20, [sp, #-16]!
|
|
str x21, [sp, #-16]!
|
|
|
|
stp x0, x1, [sp, #-16]!
|
|
sub sp, sp, #16
|
|
|
|
mov x0, sp
|
|
mov x1, #8
|
|
mov w2, wzr
|
|
mov x3, #0
|
|
bl svcGetInfo
|
|
mov w6, w0
|
|
ldr x7, [sp], #16
|
|
|
|
ldp x0, x1, [sp], #16
|
|
|
|
ldr x21, [sp], #16
|
|
ldp x19, x20, [sp], #16
|
|
ldp x17, x18, [sp], #16
|
|
ldp x15, x16, [sp], #16
|
|
ldp x13, x14, [sp], #16
|
|
ldp x11, x12, [sp], #16
|
|
ldp x9, x10, [sp], #16
|
|
|
|
// Abort when svcGetInfo failed.
|
|
cbnz w6, __libnx_exception_entry_abort
|
|
|
|
// Abort when IsCurrentProcessBeingDebugged is set where __nx_exception_ignoredebug==0.
|
|
adrp x6, __nx_exception_ignoredebug
|
|
ldr w5, [x6, #:lo12:__nx_exception_ignoredebug]
|
|
|
|
cbnz w5, __libnx_exception_entry_start
|
|
cbnz x7, __libnx_exception_entry_abort
|
|
|
|
__libnx_exception_entry_start:
|
|
adrp x2, __nx_exceptiondump
|
|
add x2, x2, #:lo12:__nx_exceptiondump
|
|
mov x5, x2
|
|
|
|
// error_desc
|
|
str w0, [x2], #4
|
|
// pad
|
|
str wzr, [x2], #4
|
|
str wzr, [x2], #4
|
|
str wzr, [x2], #4
|
|
|
|
// GPRs 0..8
|
|
ldp x3, x4, [x1]
|
|
str x5, [x1], #16 // x0 = __nx_exceptiondump
|
|
stp x3, x4, [x2], #16
|
|
ldp x3, x4, [x1], #16
|
|
stp x3, x4, [x2], #16
|
|
ldp x3, x4, [x1], #16
|
|
stp x3, x4, [x2], #16
|
|
ldp x3, x4, [x1], #16
|
|
stp x3, x4, [x2], #16
|
|
ldr x3, [x1], #8
|
|
str x3, [x2], #8
|
|
|
|
// GPRs 9..28
|
|
str x9, [x2], #8
|
|
stp x10, x11, [x2], #16
|
|
stp x12, x13, [x2], #16
|
|
stp x14, x15, [x2], #16
|
|
stp x16, x17, [x2], #16
|
|
stp x18, x19, [x2], #16
|
|
stp x20, x21, [x2], #16
|
|
stp x22, x23, [x2], #16
|
|
stp x24, x25, [x2], #16
|
|
stp x26, x27, [x2], #16
|
|
str x28, [x2], #8
|
|
|
|
// fp
|
|
str x29, [x2], #8
|
|
|
|
// lr
|
|
ldr x3, [x1], #8
|
|
str x3, [x2], #8
|
|
|
|
// sp
|
|
adrp x4, __nx_exception_stack
|
|
add x4, x4, #:lo12:__nx_exception_stack
|
|
|
|
adrp x5, __nx_exception_stack_size
|
|
ldr x5, [x5, #:lo12:__nx_exception_stack_size]
|
|
add x4, x4, x5
|
|
|
|
ldr x3, [x1]
|
|
str x4, [x1], #8 // sp = __nx_exception_stack + __nx_exception_stack_size
|
|
str x3, [x2], #8
|
|
|
|
// elr_el1 (pc)
|
|
adrp x4, __libnx_exception_returnentry
|
|
add x4, x4, #:lo12:__libnx_exception_returnentry
|
|
|
|
ldr x3, [x1]
|
|
str x4, [x1], #8 // elr_el1 = __libnx_exception_returnentry
|
|
str x3, [x2], #8
|
|
|
|
// padding
|
|
str xzr, [x2], #8
|
|
|
|
// fpu_gprs
|
|
stp q0, q1, [x2], #32
|
|
stp q2, q3, [x2], #32
|
|
stp q4, q5, [x2], #32
|
|
stp q6, q7, [x2], #32
|
|
stp q8, q9, [x2], #32
|
|
stp q10, q11, [x2], #32
|
|
stp q12, q13, [x2], #32
|
|
stp q14, q15, [x2], #32
|
|
stp q16, q17, [x2], #32
|
|
stp q18, q19, [x2], #32
|
|
stp q20, q21, [x2], #32
|
|
stp q22, q23, [x2], #32
|
|
stp q24, q25, [x2], #32
|
|
stp q26, q27, [x2], #32
|
|
stp q28, q29, [x2], #32
|
|
stp q30, q31, [x2], #32
|
|
|
|
// 4 u32s: pstate, afsr0, afsr1, and esr.
|
|
ldr w3, [x1], #4
|
|
str w3, [x2], #4
|
|
ldr w3, [x1], #4
|
|
str w3, [x2], #4
|
|
ldr w3, [x1], #4
|
|
str w3, [x2], #4
|
|
ldr w3, [x1], #4
|
|
str w3, [x2], #4
|
|
|
|
//far
|
|
ldr x3, [x1], #8
|
|
str x3, [x2], #8
|
|
|
|
mov w0, wzr
|
|
b __libnx_exception_entry_end
|
|
|
|
__libnx_exception_entry_abort:
|
|
mov w0, #0xf801
|
|
__libnx_exception_entry_end:
|
|
bl svcReturnFromException
|
|
b .
|
|
CODE_END
|
|
|
|
// Jumped to by kernel in svcReturnFromException via the overridden elr_el1, with x0 set to __nx_exceptiondump.
|
|
CODE_BEGIN __libnx_exception_returnentry
|
|
bl __libnx_exception_handler
|
|
|
|
mov w0, wzr
|
|
mov x1, #0
|
|
mov x2, #0
|
|
bl svcBreak
|
|
b .
|
|
CODE_END
|
|
|