Commit | Line | Data |
---|---|---|
e22438f8 AL |
1 | /* |
2 | * thunks.S - assembly helpers for mixed-bitness code | |
3 | * Copyright (c) 2015 Andrew Lutomirski | |
4 | * | |
5 | * This program is free software; you can redistribute it and/or modify | |
6 | * it under the terms and conditions of the GNU General Public License, | |
7 | * version 2, as published by the Free Software Foundation. | |
8 | * | |
9 | * This program is distributed in the hope it will be useful, but | |
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
12 | * General Public License for more details. | |
13 | * | |
14 | * These are little helpers that make it easier to switch bitness on | |
15 | * the fly. | |
16 | */ | |
17 | ||
18 | .text | |
19 | ||
20 | .global call32_from_64 | |
21 | .type call32_from_64, @function | |
22 | call32_from_64: | |
23 | // rdi: stack to use | |
24 | // esi: function to call | |
25 | ||
26 | // Save registers | |
27 | pushq %rbx | |
28 | pushq %rbp | |
29 | pushq %r12 | |
30 | pushq %r13 | |
31 | pushq %r14 | |
32 | pushq %r15 | |
33 | pushfq | |
34 | ||
35 | // Switch stacks | |
36 | mov %rsp,(%rdi) | |
37 | mov %rdi,%rsp | |
38 | ||
39 | // Switch to compatibility mode | |
40 | pushq $0x23 /* USER32_CS */ | |
41 | pushq $1f | |
42 | lretq | |
43 | ||
44 | 1: | |
45 | .code32 | |
46 | // Call the function | |
47 | call *%esi | |
48 | // Switch back to long mode | |
49 | jmp $0x33,$1f | |
50 | .code64 | |
51 | ||
52 | 1: | |
53 | // Restore the stack | |
54 | mov (%rsp),%rsp | |
55 | ||
56 | // Restore registers | |
57 | popfq | |
58 | popq %r15 | |
59 | popq %r14 | |
60 | popq %r13 | |
61 | popq %r12 | |
62 | popq %rbp | |
63 | popq %rbx | |
64 | ||
65 | ret | |
66 | ||
67 | .size call32_from_64, .-call32_from_64 |