diff options
Diffstat (limited to 'tools/testing/selftests/x86/thunks_32.S')
-rw-r--r-- | tools/testing/selftests/x86/thunks_32.S | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/tools/testing/selftests/x86/thunks_32.S b/tools/testing/selftests/x86/thunks_32.S new file mode 100644 index 000000000..29b644bb9 --- /dev/null +++ b/tools/testing/selftests/x86/thunks_32.S @@ -0,0 +1,55 @@ +/* + * thunks_32.S - assembly helpers for mixed-bitness code + * Copyright (c) 2015 Denys Vlasenko + * + * 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 + .code32 + + .global call64_from_32 + .type call32_from_64, @function + + // 4(%esp): function to call +call64_from_32: + // Fetch function address + mov 4(%esp), %eax + + // Save registers which are callee-clobbered by 64-bit ABI + push %ecx + push %edx + push %esi + push %edi + + // Switch to long mode + jmp $0x33,$1f +1: .code64 + + // Call the function + call *%rax + + // Switch to compatibility mode + push $0x23 /* USER32_CS */ + .code32; push $1f; .code64 /* hack: can't have X86_64_32S relocation in 32-bit ELF */ + lretq +1: .code32 + + pop %edi + pop %esi + pop %edx + pop %ecx + + ret + +.size call64_from_32, .-call64_from_32 |