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 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
|
;#
;# This file is a part of NSIS.
;#
;# Copyright (C) 2014-2018 Anders Kjersem
;#
;# Licensed under the zlib/libpng license (the "License");
;# you may not use this file except in compliance with the License.
;#
;# Licence details can be found in the file COPYING.
;#
;# This software is provided 'as-is', without any express or implied
;# warranty.
;#
;#
;# MASM:
;# ml64.exe /c Call-amd64.S
;#
;# Notes:
;# * MASM does not accept 0x* constants and GAS does not accept *h constants in Intel mode, must use decimal!
;#
; .if 0
;# MASM
SECTION_DATA equ .data
SECTION_CODE equ .code
FUNC_DECL MACRO name
name PROC
ENDM
FUNC_END MACRO name
name ENDP
ENDM
;# ~MASM
IF 0
; .else
;# GNU
.intel_syntax noprefix
.set __GNU__,1
#define IFDEF .ifdef
#define ELSE .else
#define ENDIF .endif
#define SECTION_DATA .data
#define SECTION_CODE .text
#define END .end
#define EXTERN .extern
.macro FUNC_DECL name
.global \name
.func \name
\name:
.endm
.macro FUNC_END name
.endfunc
.endm
;# ~GNU
ENDIF
IFDEF SYSTEM_LOG_DEBUG
EXTERN __imp_IsDebuggerPresent : PROC
ENDIF
EXTERN GetProcOffset : PROC
EXTERN GetParamsOffset : PROC
EXTERN GetSizeOfProcParam : PROC
EXTERN GetValueOffsetParam : PROC
EXTERN SetCallProcResultValues : PROC
SECTION_CODE
FUNC_DECL CallProc2 ;# rcx=SystemProc* edx=ParamCount
mov [rsp+8], r12
mov [rsp+16], r13
mov [rsp+24], r14
;#mov [rsp+32], r15
;# The stack is unaligned on function entry. We have to calculate the required
;# stack size for our parameters + maybe 8 padding bytes to end up 16 byte aligned.
IFDEF __GNU__
#define pSystemProc r14
ELSE
pSystemProc equ r14
ENDIF
mov pSystemProc, rcx ;# Save SystemProc*
;# Not required since we zero-extend eax: xor rax, rax
mov r13d, edx ;# Save ParamCount
imul eax, edx, 8
and edx, 1
jnz noparamalignpadding
lea eax, [eax+8] ;# sizeof(params) + 8 will make us 16 byte aligned
noparamalignpadding:
cmp eax, 40 ;# The ABI guarantees shadow space for the 4 register parameters
ja computedstacksize
mov eax, 40 ;# Minimum (4*8) + 8 to align
computedstacksize:
mov r12d, eax ;# Save stack size (Zero-extended mov)
sub rsp, r12
IFDEF SYSTEM_LOG_DEBUG
;# BUGBUG: Remove this
call qword ptr [__imp_IsDebuggerPresent]
test eax, eax
jz nodbgbrk
int 3
nodbgbrk:
ENDIF
;# We are going to set all stack parameters including the first 4,
;# it does not hurt to do that and it allows us to copy them to
;# their registers without reading pSystemProc->Params[1..3] again
call GetSizeOfProcParam
mov r9, rax ;# Store sizeof(ProcParameter)
call GetValueOffsetParam
mov r8, rax ;# Store FIELD_OFFSET(ProcParameter,Value)
call GetParamsOffset
lea r10, [pSystemProc+rax] ;# Store pSystemProc+FIELD_OFFSET(SystemProc,Params)
mov ecx, r13d ;# Zero-extended mov
test rcx, rcx
jz callthefunc
setparameter:
mov rax, r9
mul rcx ;# rax = sizeof(ProcParameter) * paramidx (paramidx is 1 based because the return value is stored in Params[0])
add rax, r10 ;# rax += pSystemProc->Params
mov rax, qword ptr [rax+r8] ;# rax = pSystemProc->Params[paramidx].Value
dec rcx
mov [rsp+(8*rcx)], rax
inc rcx
loop setparameter
;# The 4 parameter registers are all volatile so we might as well assign all of them:
;# setparam4:
;# cmp r13d, 4
;# jb setparam3
mov r9, [rsp+(8*3)]
;# setparam3:
;# cmp r13d, 3
;# jb setparam2
mov r8, [rsp+(8*2)]
;# setparam2:
;# cmp r13d, 2
;# jb setparam1
mov rdx, [rsp+(8*1)]
;# setparam1:
;# cmp r13d, 1
;# jb callthefunc
mov rcx, [rsp+(8*0)]
callthefunc:
call GetProcOffset
mov r10, qword ptr [pSystemProc+rax]
xor rax, rax ;# Fix bug #1535007
call r10
mov rcx, pSystemProc
mov rdx, rax ;# Return value
call SetCallProcResultValues ;# Store GetLastError() and return value
;# mov rax, pSystemProc has been performed by SetCallProcResultValues
;# Epilog:
;# http://msdn.microsoft.com/en-us/library/tawsa7cb claims that only
;# add/lea rsp and pop is valid in the epilog. Unwind might fail on our version?
add rsp, r12 ;# Restore stack
;# Restore nonvolatile registers:
mov r12, [rsp+8]
mov r13, [rsp+16]
mov r14, [rsp+24]
;#mov r15, [rsp+32]
ret
FUNC_END CallProc2
END
|