[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/compat/ndis/winx64_wrap.S

Version: -  FREEBSD  -  FREEBSD7  -  FREEBSD71  -  FREEBSD70  -  FREEBSD6  -  FREEBSD64  -  FREEBSD63  -  FREEBSD62  -  FREEBSD61  -  FREEBSD60  -  FREEBSD5  -  FREEBSD55  -  FREEBSD54  -  FREEBSD53  -  FREEBSD52  -  FREEBSD51  -  FREEBSD50  -  FREEBSD4  -  FREEBSD3  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  OPENSOLARIS  -  minix-3-1-1  -  TRUSTEDBSD-SEBSD  -  FREEBSD-LIBC  -  FREEBSD7-LIBC  -  FREEBSD6-LIBC  -  GLIBC27 
SearchContext: -  none  -  excerpts  -  bigexcerpts 

  1 /*-
  2  * Copyright (c) 2005
  3  *      Bill Paul <wpaul@windriver.com>.  All rights reserved.
  4  *
  5  * Redistribution and use in source and binary forms, with or without
  6  * modification, are permitted provided that the following conditions
  7  * are met:
  8  * 1. Redistributions of source code must retain the above copyright
  9  *    notice, this list of conditions and the following disclaimer.
 10  * 2. Redistributions in binary form must reproduce the above copyright
 11  *    notice, this list of conditions and the following disclaimer in the
 12  *    documentation and/or other materials provided with the distribution.
 13  * 3. All advertising materials mentioning features or use of this software
 14  *    must display the following acknowledgement:
 15  *      This product includes software developed by Bill Paul.
 16  * 4. Neither the name of the author nor the names of any co-contributors
 17  *    may be used to endorse or promote products derived from this software
 18  *    without specific prior written permission.
 19  *
 20  * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
 21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 23  * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
 24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 30  * THE POSSIBILITY OF SUCH DAMAGE.
 31  *
 32  * The x86_64 callback routines were written and graciously submitted
 33  * by Ville-Pertti Keinonen <will@exomi.com>.
 34  *
 35  * $FreeBSD: src/sys/compat/ndis/winx64_wrap.S,v 1.4 2005/04/16 04:47:15 wpaul Exp $
 36  */
 37 
 38 #include <machine/asmacros.h>
 39 
 40 /*
 41  * Wrapper for handling up to 16 arguments. We can't really
 42  * know how many arguments the caller will pass us. I'm taking an
 43  * educated guess that we'll never get over 16. Handling too
 44  * few arguments is bad. Handling too many is inefficient, but
 45  * not fatal. If someone can think of a way to handle an arbitrary
 46  * number of arguments with more elegant code, freel free to let
 47  * me know.
 48  *
 49  * Standard amd64 calling conventions specify the following registers
 50  * to be used for passing the first 6 arguments:
 51  *
 52  *   %rdi, %rsi, %rdx, %rcx, %r8, %r9
 53  *
 54  * Further arguments are passed on the stack (the 7th argument is
 55  * located immediately after the return address).
 56  *
 57  * Windows x86_64 calling conventions only pass the first 4
 58  * arguments in registers:
 59  *
 60  *   %rcx, %rdx, %r8, %r9
 61  *
 62  * Even when arguments are passed in registers, the stack must have
 63  * space reserved for those arguments.  Thus the 5th argument (the
 64  * first non-register argument) is placed 32 bytes after the return
 65  * address.  Additionally, %rdi and %rsi must be preserved. (These
 66  * two registers are not scratch registers in the standard convention.)
 67  *
 68  * Note that in this template, we load a contrived 64 bit address into
 69  * %r11 to represent our jump address. This is to guarantee that the
 70  * assembler leaves enough room to patch in an absolute 64-bit address
 71  * later. The idea behind this code is that we want to avoid having to
 72  * manually create all the wrapper functions at compile time with
 73  * a bunch of macros. This is doable, but a) messy and b) requires
 74  * us to maintain two separate tables (one for the UNIX function
 75  * pointers and another with the wrappers). This means I'd have to
 76  * update two different tables each time I added a function.
 77  *
 78  * To avoid this, we create the wrappers at runtime instead. The
 79  * image patch tables now contain two pointers: one two the normal
 80  * routine, and a blank one for the wrapper. To construct a wrapper,
 81  * we allocate some memory and copy the template function into it,
 82  * then patch the function pointer for the routine we want to wrap
 83  * into the newly created wrapper. The subr_pe module can then
 84  * simply patch the wrapper routine into the jump table into the
 85  * windows image. As a bonus, the wrapper pointer not only serves
 86  * as the wrapper entry point address, it's also a data pointer
 87  * that we can pass to free() later when we unload the module.
 88  */
 89 
 90         .globl x86_64_wrap_call
 91         .globl x86_64_wrap_end
 92 
 93 ENTRY(x86_64_wrap)
 94         push    %rbp            # insure that the stack
 95         mov     %rsp,%rbp       # is 16-byte aligned
 96         and     $-16,%rsp       #
 97         subq    $96,%rsp        # allocate space on stack
 98         mov     %rsi,96-8(%rsp) # save %rsi
 99         mov     %rdi,96-16(%rsp)# save %rdi
100         mov     %rcx,%r10       # temporarily save %rcx in scratch
101         lea     56+8(%rbp),%rsi # source == old stack top (stack+56)
102         mov     %rsp,%rdi       # destination == new stack top
103         mov     $10,%rcx        # count == 10 quadwords
104         rep
105         movsq                   # copy old stack contents to new location
106         mov     %r10,%rdi       # set up arg0 (%rcx -> %rdi)
107         mov     %rdx,%rsi       # set up arg1 (%rdx -> %rsi)
108         mov     %r8,%rdx        # set up arg2 (%r8 -> %rdx)
109         mov     %r9,%rcx        # set up arg3 (%r9 -> %rcx)
110         mov     40+8(%rbp),%r8  # set up arg4 (stack+40 -> %r8)
111         mov     48+8(%rbp),%r9  # set up arg5 (stack+48 -> %r9)
112         xor     %rax,%rax       # clear return value
113 x86_64_wrap_call:
114         mov     $0xFF00FF00FF00FF00,%r11
115         callq   *%r11           # call routine
116         mov     96-16(%rsp),%rdi# restore %rdi
117         mov     96-8(%rsp),%rsi # restore %rsi
118         leave                   # delete space on stack
119         ret
120 x86_64_wrap_end:
121 
122 /*
123  * Functions for invoking x86_64 callbacks.  In each case, the first
124  * argument is a pointer to the function.
125  */
126 
127 ENTRY(x86_64_call1)
128         subq    $8,%rsp
129         mov     %rsi,%rcx
130         call    *%rdi
131         addq    $8,%rsp
132         ret
133 
134 ENTRY(x86_64_call2)
135         subq    $24,%rsp
136         mov     %rsi,%rcx
137         /* %rdx is already correct */
138         call    *%rdi
139         addq    $24,%rsp
140         ret
141 
142 ENTRY(x86_64_call3)
143         subq    $24,%rsp
144         mov     %rcx,%r8
145         mov     %rsi,%rcx
146         call    *%rdi
147         addq    $24,%rsp
148         ret
149 
150 ENTRY(x86_64_call4)
151         subq    $40,%rsp
152         mov     %r8,%r9
153         mov     %rcx,%r8
154         mov     %rsi,%rcx
155         call    *%rdi
156         addq    $40,%rsp
157         ret
158 
159 ENTRY(x86_64_call5)
160         subq    $40,%rsp
161         mov     %r9,32(%rsp)
162         mov     %r8,%r9
163         mov     %rcx,%r8
164         mov     %rsi,%rcx
165         call    *%rdi
166         addq    $40,%rsp
167         ret
168 
169 ENTRY(x86_64_call6)
170         subq    $56,%rsp
171         mov     56+8(%rsp),%rax
172         mov     %r9,32(%rsp)
173         mov     %rax,40(%rsp)
174         mov     %r8,%r9
175         mov     %rcx,%r8
176         mov     %rsi,%rcx
177         call    *%rdi
178         addq    $56,%rsp
179         ret

Cache object: 1b948cceca65704370e7df260179b4dd


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.