| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2009 The Native Client Authors. All rights reserved. | 2 * Copyright (c) 2011 The Native Client Authors. All rights reserved. |
| 3 * Use of this source code is governed by a BSD-style license that can | 3 * Use of this source code is governed by a BSD-style license that can be |
| 4 * be found in the LICENSE file. | 4 * found in the LICENSE file. |
| 5 */ | 5 */ |
| 6 | 6 |
| 7 /* | 7 /* |
| 8 * This code gets executed when switching from the 64-bit service | 8 * This code gets executed when switching from the 64-bit service |
| 9 * runtime to a 32-bit nacl module. NaClSwitch has one parameter only, | 9 * runtime to a 32-bit nacl module. NaClSwitch has one parameter only, |
| 10 * which is a struct passed by reference. | 10 * which is a struct passed by reference. |
| 11 */ | 11 */ |
| 12 | 12 |
| 13 #include "native_client/src/trusted/service_runtime/nacl_config.h" | 13 #include "native_client/src/trusted/service_runtime/nacl_config.h" |
| 14 | 14 |
| 15 /* | 15 /* |
| 16 * This function does not return. Thus, we need to preserve | 16 * This function does not return. Thus, we need to preserve |
| 17 * any callee-saved registers. | 17 * any callee-saved registers. |
| 18 */ | 18 */ |
| 19 | 19 |
| 20 .text | 20 .text |
| 21 .globl IDENTIFIER(NaClSwitch) | 21 .globl IDENTIFIER(NaClSwitch) |
| 22 HIDDEN(NaClSwitch) | 22 HIDDEN(NaClSwitch) |
| 23 IDENTIFIER(NaClSwitch): | 23 IDENTIFIER(NaClSwitch): |
| 24 #if NACL_WINDOWS | 24 #if NACL_WINDOWS |
| 25 /* if Windows, 1st param is already in %rcx, not %rdi */ | 25 /* if Windows, 1st param is already in %rcx, not %rdi */ |
| 26 mov %rcx, %rdi | |
| 27 #elif NACL_LINUX || NACL_OSX | 26 #elif NACL_LINUX || NACL_OSX |
| 28 /* elif Linux/OSX, 1st param is already in %rdi. */ | 27 /* elif Linux/OSX, 1st param is already in %rdi. */ |
| 28 mov %rdi, %rcx |
| 29 #else | 29 #else |
| 30 # error "What OS/compiler is the service runtime being compiled with?" | 30 # error "What OS/compiler is the service runtime being compiled with?" |
| 31 #endif | 31 #endif |
| 32 | 32 |
| 33 movq 0x8(%rdi), %rbx | 33 movq 0x8(%rcx), %rbx |
| 34 movq 0x20(%rdi), %rbp | 34 movq 0x20(%rcx), %rbp |
| 35 movq 0x60(%rdi), %r12 | 35 movq 0x60(%rcx), %r12 |
| 36 movq 0x68(%rdi), %r13 | 36 movq 0x68(%rcx), %r13 |
| 37 movq 0x70(%rdi), %r14 | 37 movq 0x70(%rcx), %r14 |
| 38 movq 0x78(%rdi), %r15 | 38 movq 0x78(%rcx), %r15 |
| 39 | 39 |
| 40 /* there is no springboard for x86_64 */ | 40 /* there is no springboard for x86_64 */ |
| 41 movq 0x38(%rdi), %rsp /* rsp -- switch stack */ | 41 movq 0x38(%rcx), %rsp /* rsp -- switch stack */ |
| 42 movq 0x90(%rdi), %rax /* syscall return */ | 42 movq 0x90(%rcx), %rax /* syscall return */ |
| 43 jmp *0x88(%rdi) | 43 |
| 44 /* | 44 /* |
| 45 * This leaves %rdi pointing to the thread context, but that | 45 * %rdi is the first argument in the user calling convention. |
| 46 * When starting the initial thread, we are passing the address |
| 47 * of the parameter block here. The initial stack pointer has |
| 48 * been adjusted to one word below there, to insert a dummy |
| 49 * return address for the user entry point function. |
| 50 */ |
| 51 leal 8(%rsp), %edi |
| 52 |
| 53 /* |
| 54 * Zero all unused registers. The 32-bit instructions |
| 55 * are a byte shorter than their 64-bit counterparts |
| 56 * when the target register is one of the first eight, |
| 57 * and they implicitly zero the high halves. |
| 58 */ |
| 59 xorl %edx, %edx |
| 60 movl %edx, %esi |
| 61 movq %rdx, %r8 |
| 62 movq %rdx, %r9 |
| 63 movq %rdx, %r10 |
| 64 movq %rdx, %r11 |
| 65 |
| 66 jmp *0x88(%rcx) |
| 67 /* |
| 68 * This leaves %rcx pointing to the thread context, but that |
| 46 * should be memory that's inaccessible by NaCl module code. | 69 * should be memory that's inaccessible by NaCl module code. |
| 47 */ | 70 */ |
| OLD | NEW |