| 1 | /* SPDX-License-Identifier: GPL-2.0-only */
|
| 2 | /*
|
| 3 | * thunks.S - assembly helpers for mixed-bitness code
|
| 4 | * Copyright (c) 2015 Andrew Lutomirski
|
| 5 | *
|
| 6 | * These are little helpers that make it easier to switch bitness on
|
| 7 | * the fly.
|
| 8 | */
|
| 9 |
|
| 10 | .text
|
| 11 |
|
| 12 | .global call32_from_64
|
| 13 | .type call32_from_64, @function
|
| 14 | call32_from_64:
|
| 15 | // rdi: stack to use
|
| 16 | // esi: function to call
|
| 17 |
|
| 18 | // Save registers
|
| 19 | pushq %rbx
|
| 20 | pushq %rbp
|
| 21 | pushq %r12
|
| 22 | pushq %r13
|
| 23 | pushq %r14
|
| 24 | pushq %r15
|
| 25 | pushfq
|
| 26 |
|
| 27 | // Switch stacks
|
| 28 | mov %rsp,(%rdi)
|
| 29 | mov %rdi,%rsp
|
| 30 |
|
| 31 | // Switch to compatibility mode
|
| 32 | pushq $0x23 /* USER32_CS */
|
| 33 | pushq $1f
|
| 34 | lretq
|
| 35 |
|
| 36 | 1:
|
| 37 | .code32
|
| 38 | // Call the function
|
| 39 | call *%esi
|
| 40 | // Switch back to long mode
|
| 41 | jmp $0x33,$1f
|
| 42 | .code64
|
| 43 |
|
| 44 | 1:
|
| 45 | // Restore the stack
|
| 46 | mov (%rsp),%rsp
|
| 47 |
|
| 48 | // Restore registers
|
| 49 | popfq
|
| 50 | popq %r15
|
| 51 | popq %r14
|
| 52 | popq %r13
|
| 53 | popq %r12
|
| 54 | popq %rbp
|
| 55 | popq %rbx
|
| 56 |
|
| 57 | ret
|
| 58 |
|
| 59 | .size call32_from_64, .-call32_from_64
|
| 60 |
|
| 61 | .section .note.GNU-stack,"",%progbits
|