/usr/src/ndiswrapper-1.59/lin2win.S is in ndiswrapper-dkms 1.59-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | /*
* Copyright (C) 2011 Pavel Roskin
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that 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.
*
*/
#include <linux/linkage.h>
.text
#define WORD_BYTES 8
#define LINUX_REG_ARGS 6
#define WINDOWS_REG_ARGS 4
/* %rbp is saved to create a stack frame, which can help with debugging */
#define SAVED_REGS 1
/*
* When calling a Windows function, stack space is allocated for at least 4
* arguments even if the number of arguments is less than 4. The value of
* true is -1 in assembler, so we multiply it by another true value.
*/
#define stack_args(argc) \
(WINDOWS_REG_ARGS + \
(0 < 1) * (argc > WINDOWS_REG_ARGS) * (argc - WINDOWS_REG_ARGS))
/* Full required change of stack pointer, in words */
#define stack_words_raw(argc) (stack_args(argc) + SAVED_REGS + 1)
/* Full actual change of stack pointer, in words (must be even) */
#define stack_words_aligned(argc) ((stack_words_raw(argc) + 1) & ~1)
/* Space allocated for Linux arguments on stack */
#define stack_space(argc) \
((stack_words_aligned(argc) - SAVED_REGS - 1) * WORD_BYTES)
/*
* lin2win_win_arg(N) gives the address of the Nth Windows argument on our
* stack frame. %rsp points to the first argument. The Nth argument is
* therefore at ((N - 1) * 8)(%rsp).
*
* Don't call with N less than 5!
*/
#define lin2win_win_arg(n) ((n - 1) * WORD_BYTES)(%rsp)
/*
* lin2win_lin_arg(N, ARGC) gives the address of the Nth Linux argument after
* the stack has been prepared for a Windows function call with ARGC arguments.
*
* When called from Linux, the Nth argument is at ((N - 6) * 8)(%rsp). We add
* the allocated stack space and saved registers to compensate for %rsp change.
*
* Don't call with N less than 7!
*/
#define lin2win_lin_arg(n, argc) \
(stack_space(argc) + \
(SAVED_REGS + n - LINUX_REG_ARGS) * WORD_BYTES)(%rsp)
/*
* lin2win(func, winarg1, winarg2, ...)
* Call Windows FUNC function with ARGC arguments WINARG1, WINARG2, ...
* We get (ARGC + 1) arguments.
*/
.macro lin2win name, argc
.type \name, @function
ENTRY(\name)
/* Create a call frame - it's optional, but good for debugging */
.cfi_startproc
push %rbp
.cfi_def_cfa %rsp, 2 * WORD_BYTES
.cfi_offset %rbp, -2 * WORD_BYTES
mov %rsp, %rbp
.cfi_def_cfa %rbp, 2 * WORD_BYTES
/* Allocate space for Windows arguments */
sub $stack_space(\argc), %rsp
/* arg7 to winarg6 */
.if (\argc >= 6)
mov lin2win_lin_arg(7, \argc), %r11
mov %r11, lin2win_win_arg(6)
.endif
/* arg6 to winarg5 */
.if (\argc >= 5)
mov %r9, lin2win_win_arg(5)
.endif
/* arg5 to winarg4 */
.if (\argc >= 4)
mov %r8, %r9
.endif
/* arg4 to winarg3 */
.if (\argc >= 3)
mov %rcx, %r8
.endif
/* arg3 to winarg2 - nothing needed, both are in %rdx */
/* arg2 to winarg1 */
.if (\argc >= 1)
mov %rsi, %rcx
.endif
/* Call function (arg1) */
call *%rdi
/* Reclaim space for Windows arguments */
add $stack_space(\argc), %rsp
/* Return to the caller */
leave
.cfi_def_cfa %rsp, WORD_BYTES
.cfi_restore %rbp
ret
.cfi_endproc
.size \name, (. - \name)
.endm
/* Define lin2winN functions */
lin2win lin2win0, 0
lin2win lin2win1, 1
lin2win lin2win2, 2
lin2win lin2win3, 3
lin2win lin2win4, 4
lin2win lin2win5, 5
lin2win lin2win6, 6
|