| // Mark stack as non-executable |
| #if defined(__linux__) && defined(__ELF__) |
| .section .note.GNU-stack, "", @progbits |
| #endif |
| |
| .text |
| |
| .globl upcall_new_stack |
| .globl upcall_del_stack |
| .globl __morestack |
| |
| .hidden __morestack |
| |
| .cfi_startproc |
| .set nomips16 |
| .ent __morestack |
| __morestack: |
| .set noreorder |
| .set nomacro |
| |
| addiu $29, $29, -12 |
| sw $31, 8($29) |
| sw $30, 4($29) |
| sw $23, 0($29) |
| |
| // 24 = 12 (current) + 12 (previous) |
| .cfi_def_cfa_offset 24 |
| .cfi_offset 31, -4 |
| .cfi_offset 30, -20 |
| .cfi_offset 23, -24 |
| |
| move $23, $28 |
| move $30, $29 |
| .cfi_def_cfa_register 30 |
| |
| // Save argument registers of the original function |
| addiu $29, $29, -32 |
| sw $4, 16($29) |
| sw $5, 20($29) |
| sw $6, 24($29) |
| sw $7, 28($29) |
| |
| move $4, $14 // Size of stack arguments |
| addu $5, $30, 24 // Address of stack arguments |
| move $6, $15 // The amount of stack needed |
| |
| move $28, $23 |
| lw $25, %call16(upcall_new_stack)($23) |
| jalr $25 |
| nop |
| |
| // Pop the saved arguments |
| lw $4, 16($29) |
| lw $5, 20($29) |
| lw $6, 24($29) |
| lw $7, 28($29) |
| addiu $29, $29, 32 |
| |
| lw $24, 8($30) // Grab the return pointer. |
| addiu $24, $24, 12 // Skip past the `lw`, `jr`, `addiu` in our parent frame |
| move $29, $2 // Switch to the new stack. |
| |
| // for PIC |
| lw $2, 12($30) |
| lw $25, 16($30) |
| |
| move $28, $23 |
| jalr $24 // Reenter the caller function |
| nop |
| |
| // Switch back to the rust stack |
| move $29, $30 |
| |
| // Save the return value |
| addiu $29, $29, -24 |
| sw $2, 16($29) |
| sw $3, 20($29) |
| |
| move $28, $23 |
| lw $25, %call16(upcall_del_stack)($23) |
| jalr $25 |
| nop |
| |
| // Restore the return value |
| lw $2, 16($29) |
| lw $3, 20($29) |
| addiu $29, $29, 24 |
| |
| lw $31, 8($29) |
| lw $30, 4($29) |
| lw $23, 0($29) |
| addiu $29, $29, 12 |
| |
| jr $31 |
| nop |
| .end __morestack |
| .cfi_endproc |