⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 win2lin_stubs.s

📁 ndis在linux下的无线网卡驱动源码
💻 S
字号:
/* *  Copyright (C) 2005 Karl Vogel, Giridhar Pemmasani * *  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>#ifdef CONFIG_X86_64/*# Windows <---> Linux register usage conversion when calling functions# V = Volatile# NV = Non Volatile (needs to be saved)##         Win                     Lin# ---------------------------------------# Rax    Return           V       Return          V# Rbx                     NV                      NV# Rcx     Arg1            V       Arg4            V# Rdx     Arg2            V       Arg3            V# Rsi                     NV      Arg2            V# Rdi                     NV      Arg1            V# Rsp                     NV                      NV# Rbp                     NV                      NV# R8      Arg3            V       Arg5            V# R9      Arg4            V       Arg6            V# R10                     V                       V# R11                     V                       V# R12                     NV                      NV# R13                     NV                      NV# R14                     NV                      NV# R15                     NV                      NV## In addition, Linux uses %rax to indicate number of SSE registers used# when variadic functions are called. Since there is no way to obtain this# from Windows, for now, we just assume this is 0 (hence %rax is cleared).## Windows pushes arguments 5 and higher onto stack in case of integer# variables and 4 and higher in case of floating point variabes (passed# in SSE registers).In a windows function, the stackframe/registers look like this:# 0x0048 ....# 0x0040 arg8# 0x0038 arg7# 0x0030 arg6# 0x0028 arg5# 0x0020 register spill space# 0x0018 register spill space# 0x0010 register spill space# 0x0008 register spill space# 0x0000 ret# register spill space is same irrespective of number of arguments - even# if Windows function takes less than 4 arguments, 32 bytes above return# address is reserved for the functionIn Linux it should look like:# 0x0018 ....# 0x0010 arg8# 0x0008 arg7# 0x0000 ret*/## setup for Windows to Linux function call#	.text.macro win2lin_prolog	push	%rsi	push	%rdi.endm.macro win2lin_epilog	pop	%rdi	pop	%rsi.endm# when Windows function calls Linux function, the function address is in %r10.macro call_lin_func	xor	%rax, %rax	# rax indicates number of SSE regs	call	*%r10.endm# before prolog, 0(%rsp) is return address, 8(%rsp) would be arg1# (but it is in register) and so on, so n'th arg would be at n*8(%rsp)# for n > 4. But in prolog, we push 2 registers that are non-volaile in# Windows, but volatile in Linux. So after prolog, args are at (n+2)*8(%rsp)#define win2lin_win_arg(n) (n+2)*8(%rsp)#define win2lin_arg1 mov %rcx, %rdi#define win2lin_arg2 mov %rdx, %rsi#define win2lin_arg3 mov %r8, %rdx#define win2lin_arg4 mov %r9, %rcx#define win2lin_arg5 mov win2lin_win_arg(5), %r8#define win2lin_arg6 mov win2lin_win_arg(6), %r9win2lin0:	win2lin_prolog	call_lin_func	win2lin_epilog	retwin2lin1:	win2lin_prolog	win2lin_arg1	call_lin_func	win2lin_epilog	retwin2lin2:	win2lin_prolog	win2lin_arg1	win2lin_arg2	call_lin_func	win2lin_epilog	retwin2lin3:	win2lin_prolog	win2lin_arg1	win2lin_arg2	win2lin_arg3	call_lin_func	win2lin_epilog	retwin2lin4:	win2lin_prolog	win2lin_arg1	win2lin_arg2	win2lin_arg3	win2lin_arg4	call_lin_func	win2lin_epilog	retwin2lin5:	win2lin_prolog	win2lin_arg1	win2lin_arg2	win2lin_arg3	win2lin_arg4	win2lin_arg5	call_lin_func	win2lin_epilog	retwin2lin6:	win2lin_prolog	win2lin_arg1	win2lin_arg2	win2lin_arg3	win2lin_arg4	win2lin_arg5	win2lin_arg6	call_lin_func	win2lin_epilog	ret# Allocate stack frame for Linux arguments before calling function.# First 6 args are passed through registers, so we need space for 7 and above.# The arguments should have been copied onto stack already..macro call_lin_func_args n	sub $(\n-6)*8, %rsp	call_lin_func	add $(\n-6)*8, %rsp	.endm# m is index of Linux arg required, n is total number of args to function# After stack frame is allocated, Linux arg 7 should be at 0(%rsp),# arg 8 should be at 1*8(%rsp) and so on. So Linux arg m should be at (m-7)*8# Stack frame starts at -(n-6)*8(%rsp), so before stack frame is allocated# Linux arg m should be at (6-n+m-7)*8(%rsp)#define win2lin_lin_arg(m,n) (m-1-n)*8(%rsp)win2lin7:	win2lin_prolog	win2lin_arg1	win2lin_arg2	win2lin_arg3	win2lin_arg4	win2lin_arg5	win2lin_arg6	# copy windows argument 7 onto stack for Linux function	mov	win2lin_win_arg(7), %r11	mov	%r11, win2lin_lin_arg(7,7)	call_lin_func_args(7)	win2lin_epilog	retwin2lin8:	win2lin_prolog	win2lin_arg1	win2lin_arg2	win2lin_arg3	win2lin_arg4	win2lin_arg5	win2lin_arg6	# copy windows arguments 7 and 8 onto stack for Linux function	mov	win2lin_win_arg(7), %r11	mov	%r11, win2lin_lin_arg(7,8)	mov	win2lin_win_arg(8), %r11	mov	%r11, win2lin_lin_arg(8,8)	call_lin_func_args(8)	win2lin_epilog	retwin2lin9:win2lin10:win2lin11:win2lin12:	win2lin_prolog	# since we destroy rsi and rdi here, first copy windows	# arguments 7 through 12 onto stack for Linux function	mov	%rcx, %r11		# save rcx	lea	win2lin_win_arg(7), %rsi	# source (windows arg 7 and up)	lea	win2lin_lin_arg(7,12), %rdi	# = destination	mov	$6, %rcx			# 6 arguments	rep	movsq	mov	%r11, %rcx		# restore rcx	win2lin_arg1	win2lin_arg2	win2lin_arg3	win2lin_arg4	win2lin_arg5	win2lin_arg6	call_lin_func_args(12)	win2lin_epilog	ret#define win2lin(name, argc)			\ENTRY(win2lin_ ## name ## _ ## argc)		\	lea	name(%rip), %r10 ; 		\	jmp	win2lin ## argc#include "win2lin_stubs.h"#endif // CONFIG_X86_64

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -