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 |
62 | |