handler.s revision 2
2N/A * The contents of this file are subject to the terms of the 2N/A * Common Development and Distribution License (the "License"). 2N/A * You may not use this file except in compliance with the License. 2N/A * See the License for the specific language governing permissions 2N/A * and limitations under the License. 2N/A * When distributing Covered Code, include this CDDL HEADER in each 2N/A * If applicable, add the following below this CDDL HEADER, with the 2N/A * fields enclosed by brackets "[]" replaced with your own identifying 2N/A * information: Portions Copyright [yyyy] [name of copyright owner] 2N/A * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 2N/A * Each JMP must occupy 16 bytes 2N/A * On entry to this table, %eax will hold the return address. The 2N/A * location where we enter the table is a function of the system 2N/A * call number. The table needs the same alignment as the individual 2N/A * %eax - userland return address 2N/A * | -------------------------------------- 2N/A * v 4 | syscall arguments | 2N/A * %esp+0 | syscall number | 2N/A * -------------------------------------- 2N/A /* Save registers at the time of the syscall. */ 2N/A * The kernel drops us into the middle of the brand_handle_table 2N/A * above that then pushes that table offset onto the stack, and calls 2N/A * into brand_handler. That offset indicates the system call number 2N/A * while %eax holds the return address for the system call. We replace 2N/A * the value on the stack with the return address, and use the value to 2N/A * compute the system call number by dividing by the table entry size. 2N/A * Finish setting up our stack frame. We would normally do this 2N/A * upon entry to this function, but in this case we delayed it 2N/A * because a "sub" operation can modify flags and we wanted to 2N/A * save the flags into the gregset_t above before they get modified. 2N/A /* Look up the system call's entry in the sysent table */ 2N/A * Get the return value flag and the number of arguments from the 2N/A * Setup arguments for our emulation call. Our input arguments, 2N/A * 0 to N, will become emulation call arguments 1 to N+1. 2N/A * %ecx == number of arguments. 2N/A /* copy: %ecx 32-bit words */ 2N/A * The first parameter to the emulation callback function is a 2N/A * pointer to a sysret_t structure. 2N/A /* invoke the emulation routine */ 2N/A /* restore scratch registers */ 2N/A /* Check for syscall emulation success or failure */ 2N/A stc /* failure, set carry flag */ 2N/A jmp return /* return, %rax == errno */ 2N/A /* There is always at least one return value. */ 2N/A clc /* success, clear carry flag */ 2N/A ret /* ret to instr after syscall */