| /* | |
| * thunks.S - assembly helpers for mixed-bitness code | |
| * Copyright (c) 2015 Andrew Lutomirski | |
| * | |
| * This program is free software; you can redistribute it and/or modify | |
| * it under the terms and conditions of the GNU General Public License, | |
| * version 2, as published by the Free Software Foundation. | |
| * | |
| * This program is distributed in the hope it will be useful, but | |
| * WITHOUT ANY WARRANTY; without even the implied warranty of | |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| * General Public License for more details. | |
| * | |
| * These are little helpers that make it easier to switch bitness on | |
| * the fly. | |
| */ | |
| .text | |
| .global call32_from_64 | |
| .type call32_from_64, @function | |
| call32_from_64: | |
| // rdi: stack to use | |
| // esi: function to call | |
| // Save registers | |
| pushq %rbx | |
| pushq %rbp | |
| pushq %r12 | |
| pushq %r13 | |
| pushq %r14 | |
| pushq %r15 | |
| pushfq | |
| // Switch stacks | |
| mov %rsp,(%rdi) | |
| mov %rdi,%rsp | |
| // Switch to compatibility mode | |
| pushq $0x23 /* USER32_CS */ | |
| pushq $1f | |
| lretq | |
| 1: | |
| .code32 | |
| // Call the function | |
| call *%esi | |
| // Switch back to long mode | |
| jmp $0x33,$1f | |
| .code64 | |
| 1: | |
| // Restore the stack | |
| mov (%rsp),%rsp | |
| // Restore registers | |
| popfq | |
| popq %r15 | |
| popq %r14 | |
| popq %r13 | |
| popq %r12 | |
| popq %rbp | |
| popq %rbx | |
| ret | |
| .size call32_from_64, .-call32_from_64 |