Basic AMD64 System::Call support
git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@6444 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
parent
a7261be70c
commit
a7076ff238
9 changed files with 268 additions and 46 deletions
|
@ -26,14 +26,25 @@ docs = Split("""
|
||||||
|
|
||||||
Import('BuildPlugin env')
|
Import('BuildPlugin env')
|
||||||
|
|
||||||
if env['TARGET_ARCH'] != 'amd64':
|
defs = ['SYSTEM_EXPORTS']
|
||||||
|
msvc = 'msvc' in env['TOOLS'] or 'mstoolkit' in env['TOOLS']
|
||||||
|
|
||||||
|
if env['TARGET_ARCH'] != 'amd64' or msvc: # BUGBUG: Call-amd64.S is missing GAS macros
|
||||||
|
srcsuff = ''
|
||||||
|
if env['TARGET_ARCH'] != 'x86':
|
||||||
|
srcsuff = '-' + env['TARGET_ARCH']
|
||||||
|
defs += ['SYSTEM_NOCALLBACKS'] # BUGBUG: Remove this when CallBack() is implemented
|
||||||
|
if msvc: # BUGBUG: Remove this when GAS is fixed
|
||||||
|
defs += ['SYSTEM_PARTIALCALLSUPPORT']
|
||||||
|
filename = 'Call' + srcsuff
|
||||||
|
|
||||||
conf = env.Configure()
|
conf = env.Configure()
|
||||||
if conf.TryCompile('END', '.S'):
|
if conf.TryCompile('END', '.S'):
|
||||||
files += ['Source/Call.S']
|
files += ['Source/'+filename+'.S']
|
||||||
elif conf.TryCompile('.end', '.sx'):
|
elif conf.TryCompile('.end', '.sx'):
|
||||||
files += ['Source/Call.sx']
|
files += ['Source/'+filename+'.sx']
|
||||||
else:
|
else:
|
||||||
print 'WARNING: System.dll: unable to find assembler for Call.S'
|
print 'WARNING: System.dll: unable to find assembler for '+filename+'.S'
|
||||||
conf.Finish()
|
conf.Finish()
|
||||||
else:
|
else:
|
||||||
print 'WARNING: System.dll: missing Win64 code, dynamic function calls not supported'
|
print 'WARNING: System.dll: missing Win64 code, dynamic function calls not supported'
|
||||||
|
@ -45,7 +56,7 @@ BuildPlugin(
|
||||||
examples,
|
examples,
|
||||||
docs,
|
docs,
|
||||||
nodeflib = False,
|
nodeflib = False,
|
||||||
defines = ['SYSTEM_EXPORTS']
|
defines = defs
|
||||||
)
|
)
|
||||||
|
|
||||||
res = 'Resource/Resource.rc'
|
res = 'Resource/Resource.rc'
|
||||||
|
|
181
Contrib/System/Source/Call-amd64.S
Normal file
181
Contrib/System/Source/Call-amd64.S
Normal file
|
@ -0,0 +1,181 @@
|
||||||
|
;#
|
||||||
|
;# This file is a part of NSIS.
|
||||||
|
;#
|
||||||
|
;# Copyright (C) 2014 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
|
||||||
|
;#
|
||||||
|
|
||||||
|
; .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
|
||||||
|
|
||||||
|
#define IFDEF .ifdef
|
||||||
|
#define ELSE .else
|
||||||
|
#define ENDIF .endif
|
||||||
|
|
||||||
|
#define SECTION_DATA .data
|
||||||
|
#define SECTION_CODE .text
|
||||||
|
|
||||||
|
#define END .end
|
||||||
|
#define EXTERN .extern
|
||||||
|
|
||||||
|
;# ~GNU
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
|
||||||
|
EXTERN __imp_GetLastError : PROC
|
||||||
|
IFDEF SYSTEM_LOG_DEBUG
|
||||||
|
EXTERN __imp_IsDebuggerPresent : PROC
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
EXTERN LastError : DWORD
|
||||||
|
|
||||||
|
EXTERN GetProcOffset : PROC
|
||||||
|
EXTERN GetParamsOffset : PROC
|
||||||
|
EXTERN GetSizeOfProcParam : PROC
|
||||||
|
EXTERN GetValueOffsetParam : PROC
|
||||||
|
EXTERN SetProcResultOk : PROC
|
||||||
|
EXTERN GetErrorOption : PROC
|
||||||
|
|
||||||
|
|
||||||
|
SECTION_CODE
|
||||||
|
|
||||||
|
|
||||||
|
FUNC_DECL CallProc2 ;# rcx=SystemProc* edx=ParamCount
|
||||||
|
mov [rsp+8h], r12
|
||||||
|
mov [rsp+10h], r13
|
||||||
|
mov [rsp+18h], r14
|
||||||
|
;#mov [rsp+20h], 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.
|
||||||
|
pSystemProc equ r14
|
||||||
|
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, 28h ;# The ABI guarantees shadow space for the 4 register parameters
|
||||||
|
ja computedstacksize
|
||||||
|
mov eax, 28h ;# 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 r13, rax ;# Save return value
|
||||||
|
|
||||||
|
mov rcx, pSystemProc
|
||||||
|
call GetErrorOption
|
||||||
|
test eax, eax
|
||||||
|
jz capturegle_done
|
||||||
|
call qword ptr [__imp_GetLastError]
|
||||||
|
mov dword ptr [LastError], eax
|
||||||
|
capturegle_done:
|
||||||
|
|
||||||
|
;# proc->Params[0].Value = pSystemProc->Proc's return value
|
||||||
|
call GetParamsOffset
|
||||||
|
mov rdx, rax ;# This assumes that the next function is not going to clobber rdx!
|
||||||
|
call GetValueOffsetParam
|
||||||
|
add rdx, rax
|
||||||
|
mov qword ptr [pSystemProc+rdx], r13
|
||||||
|
|
||||||
|
mov rcx, pSystemProc
|
||||||
|
call SetProcResultOk ;# BUGBUG: This is pointless, system.c should just assume we are OK
|
||||||
|
|
||||||
|
mov rax, pSystemProc ;# Return SystemProc*
|
||||||
|
;# 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+8h]
|
||||||
|
mov r13, [rsp+10h]
|
||||||
|
mov r14, [rsp+18h]
|
||||||
|
;#mov r15, [rsp+20h]
|
||||||
|
ret
|
||||||
|
FUNC_END CallProc2
|
||||||
|
|
||||||
|
|
||||||
|
END
|
|
@ -275,6 +275,7 @@ TODO: CallProc/Back not implemeted.
|
||||||
Fake the behavior of the System plugin for the LoadImage API function so MUI works.
|
Fake the behavior of the System plugin for the LoadImage API function so MUI works.
|
||||||
BUGBUG: MUI is leaking DeleteObject and failing GetClientRect
|
BUGBUG: MUI is leaking DeleteObject and failing GetClientRect
|
||||||
*/
|
*/
|
||||||
|
#ifndef SYSTEM_PARTIALCALLSUPPORT
|
||||||
SystemProc* CallProc(SystemProc *proc)
|
SystemProc* CallProc(SystemProc *proc)
|
||||||
{
|
{
|
||||||
INT_PTR ret, *place;
|
INT_PTR ret, *place;
|
||||||
|
@ -294,12 +295,13 @@ SystemProc* CallProc(SystemProc *proc)
|
||||||
if (place) *place = ret;
|
if (place) *place = ret;
|
||||||
return proc;
|
return proc;
|
||||||
}
|
}
|
||||||
|
#endif // ~SYSTEM_PARTIALCALLSUPPORT
|
||||||
SystemProc* CallBack(SystemProc *proc)
|
SystemProc* CallBack(SystemProc *proc)
|
||||||
{
|
{
|
||||||
proc->ProcResult = PR_ERROR;
|
proc->ProcResult = PR_ERROR;
|
||||||
return proc;
|
return proc;
|
||||||
}
|
}
|
||||||
#endif
|
#endif // ~_WIN64
|
||||||
|
|
||||||
|
|
||||||
PLUGINFUNCTION(Call)
|
PLUGINFUNCTION(Call)
|
||||||
|
@ -355,7 +357,7 @@ PLUGINFUNCTION(Call)
|
||||||
proc->Params[0] = pp; // Restore old return param
|
proc->Params[0] = pp; // Restore old return param
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ParamsOut(proc);
|
ParamsOut(proc);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (proc->ProcResult != PR_CALLBACK)
|
if (proc->ProcResult != PR_CALLBACK)
|
||||||
|
@ -768,7 +770,9 @@ SystemProc *PrepareProc(BOOL NeedForCall)
|
||||||
break;
|
break;
|
||||||
case _T('!'): temp = -temp; break;
|
case _T('!'): temp = -temp; break;
|
||||||
case _T('c'):
|
case _T('c'):
|
||||||
|
#ifndef _WIN64
|
||||||
temp2 = POPT_CDECL;
|
temp2 = POPT_CDECL;
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
case _T('r'):
|
case _T('r'):
|
||||||
temp2 = POPT_ALWRETURN;
|
temp2 = POPT_ALWRETURN;
|
||||||
|
@ -993,16 +997,19 @@ void ParamsIn(SystemProc *proc)
|
||||||
#ifdef SYSTEM_LOG_DEBUG
|
#ifdef SYSTEM_LOG_DEBUG
|
||||||
{
|
{
|
||||||
TCHAR buf[666];
|
TCHAR buf[666];
|
||||||
wsprintf(buf, _T("\t\t\tParam In %d: type %d value ")SYSFMT_HEXPTR _T(" value2 0x%08X"), i,
|
UINT32 hi32 = 0;
|
||||||
par->Type, par->Value, par->_value);
|
#ifndef _WIN64
|
||||||
|
hi32 = par->_value;
|
||||||
|
#endif
|
||||||
|
wsprintf(buf, _T("\t\t\tParam In %d:\tType=%d Value=")SYSFMT_HEXPTR _T(" hi32=0x%08X"), i,
|
||||||
|
par->Type, par->Value, hi32);
|
||||||
SYSTEM_LOG_ADD(buf);
|
SYSTEM_LOG_ADD(buf);
|
||||||
SYSTEM_LOG_POST;
|
SYSTEM_LOG_POST;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (i == 0) break;
|
if (i == 0) break;
|
||||||
if (i == proc->ParamCount) i = 0;
|
if (i == proc->ParamCount) i = 0; else i++;
|
||||||
else i++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1101,7 +1108,7 @@ void ParamsOut(SystemProc *proc)
|
||||||
#ifdef SYSTEM_LOG_DEBUG
|
#ifdef SYSTEM_LOG_DEBUG
|
||||||
{
|
{
|
||||||
TCHAR dbgbuf[99];
|
TCHAR dbgbuf[99];
|
||||||
wsprintf(dbgbuf, _T(") %d:\tType=%d Optn=%d Size=%d Data="),
|
wsprintf(dbgbuf, _T(")\t%d:\tType=%d Optn=%d Size=%d Data="),
|
||||||
i, proc->Params[i].Type, proc->Params[i].Option, proc->Params[i].Size);
|
i, proc->Params[i].Type, proc->Params[i].Option, proc->Params[i].Size);
|
||||||
SYSTEM_LOG_ADD(dbgbuf);
|
SYSTEM_LOG_ADD(dbgbuf);
|
||||||
SYSTEM_LOG_ADD(realbuf);
|
SYSTEM_LOG_ADD(realbuf);
|
||||||
|
@ -1118,7 +1125,7 @@ void ParamsOut(SystemProc *proc)
|
||||||
|
|
||||||
HANDLE CreateCallback(SystemProc *cbproc)
|
HANDLE CreateCallback(SystemProc *cbproc)
|
||||||
{
|
{
|
||||||
#ifdef SYSTEM_X64
|
#ifdef SYSTEM_AMD64
|
||||||
return BUGBUG64(HANDLE) NULL;
|
return BUGBUG64(HANDLE) NULL;
|
||||||
#else
|
#else
|
||||||
char *mem;
|
char *mem;
|
||||||
|
@ -1285,7 +1292,7 @@ BOOL WINAPI DllMain(HINSTANCE hInst, DWORD fdwReason, LPVOID lpReserved)
|
||||||
#ifdef SYSTEM_X86
|
#ifdef SYSTEM_X86
|
||||||
retexpr[0] = (char) 0xC2;
|
retexpr[0] = (char) 0xC2;
|
||||||
retexpr[2] = 0x00;
|
retexpr[2] = 0x00;
|
||||||
#elif defined(SYSTEM_X64)
|
#elif defined(SYSTEM_AMD64)
|
||||||
retexpr[0] = BUGBUG64(0);
|
retexpr[0] = BUGBUG64(0);
|
||||||
#else
|
#else
|
||||||
#error TODO
|
#error TODO
|
||||||
|
@ -1329,9 +1336,9 @@ unsigned int GetErrorOption(SystemProc *proc)
|
||||||
/*
|
/*
|
||||||
Returns offset for element Proc of SystemProc structure
|
Returns offset for element Proc of SystemProc structure
|
||||||
*/
|
*/
|
||||||
unsigned int GetProcOffset(void)
|
UINT_PTR GetProcOffset(void)
|
||||||
{
|
{
|
||||||
return (unsigned int)(&(((SystemProc *)0)->Proc));
|
return (UINT_PTR)(&(((SystemProc *)0)->Proc));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1369,15 +1376,15 @@ unsigned int GetParamCount(SystemProc *proc)
|
||||||
/*
|
/*
|
||||||
Returns offset for element Params of SystemProc structure
|
Returns offset for element Params of SystemProc structure
|
||||||
*/
|
*/
|
||||||
unsigned int GetParamsOffset(void)
|
UINT_PTR GetParamsOffset(void)
|
||||||
{
|
{
|
||||||
return (unsigned int)(&(((SystemProc *)0)->Params));
|
return (UINT_PTR)(&(((SystemProc *)0)->Params));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Returns size of ProcParameter structure
|
Returns size of ProcParameter structure
|
||||||
*/
|
*/
|
||||||
unsigned int GetSizeOfProcParam(void)
|
UINT_PTR GetSizeOfProcParam(void)
|
||||||
{
|
{
|
||||||
return (sizeof(ProcParameter));
|
return (sizeof(ProcParameter));
|
||||||
}
|
}
|
||||||
|
@ -1393,11 +1400,12 @@ unsigned int GetSizeOffsetParam(void)
|
||||||
/*
|
/*
|
||||||
Returns offset for element Value of ProcParameter structure
|
Returns offset for element Value of ProcParameter structure
|
||||||
*/
|
*/
|
||||||
unsigned int GetValueOffsetParam(void)
|
UINT_PTR GetValueOffsetParam(void)
|
||||||
{
|
{
|
||||||
return (unsigned int)(&(((ProcParameter *)0)->Value));
|
return (UINT_PTR)(&(((ProcParameter *)0)->Value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef _WIN64
|
||||||
/*
|
/*
|
||||||
Returns offset for element _value of ProcParameter structure
|
Returns offset for element _value of ProcParameter structure
|
||||||
*/
|
*/
|
||||||
|
@ -1405,6 +1413,7 @@ unsigned int Get_valueOffsetParam(void)
|
||||||
{
|
{
|
||||||
return (unsigned int)(&(((ProcParameter *)0)->_value));
|
return (unsigned int)(&(((ProcParameter *)0)->_value));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Sets "CLONE" option
|
Sets "CLONE" option
|
||||||
|
|
|
@ -4,16 +4,17 @@
|
||||||
// This should probably be moved to platform.h at some point
|
// This should probably be moved to platform.h at some point
|
||||||
|
|
||||||
#if defined(_M_X64) || defined(_M_AMD64) || defined(__amd64__)
|
#if defined(_M_X64) || defined(_M_AMD64) || defined(__amd64__)
|
||||||
# define SYSTEM_X64
|
# define SYSTEM_AMD64
|
||||||
#elif defined(_M_IX86) || defined(__i386__) || defined(_X86_)
|
#elif defined(_M_IX86) || defined(__i386__) || defined(_X86_)
|
||||||
# define SYSTEM_X86
|
# define SYSTEM_X86
|
||||||
#else
|
#else
|
||||||
# error "Unknown architecture!"
|
# error "Unknown architecture!"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
#define SYSFMT_HEXPTR _T("0x%016IX")
|
# define SYSFMT_HEXPTR _T("0x%016IX")
|
||||||
#else
|
#else
|
||||||
#define SYSFMT_HEXPTR _T("0x%08X")
|
# define SYSFMT_HEXPTR _T("0x%08X")
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -25,9 +26,9 @@
|
||||||
// defined with this macro as being exported.
|
// defined with this macro as being exported.
|
||||||
|
|
||||||
#ifdef SYSTEM_EXPORTS
|
#ifdef SYSTEM_EXPORTS
|
||||||
#define SYSTEM_API __declspec(dllexport)
|
# define SYSTEM_API __declspec(dllexport)
|
||||||
#else
|
#else
|
||||||
#define SYSTEM_API __declspec(dllimport)
|
# define SYSTEM_API __declspec(dllimport) // BUGBUG: This is a plugin, who is going to import the functions directly?
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define NEW_STACK_SIZE 256*256
|
#define NEW_STACK_SIZE 256*256
|
||||||
|
@ -123,7 +124,7 @@ struct tag_CallbackThunk
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
*/
|
*/
|
||||||
char asm_code[10];
|
char asm_code[10];
|
||||||
#elif defined(SYSTEM_X64)
|
#elif defined(SYSTEM_AMD64)
|
||||||
char asm_code[BUGBUG64(1)]; // TODO: BUGBUG64
|
char asm_code[BUGBUG64(1)]; // TODO: BUGBUG64
|
||||||
#else
|
#else
|
||||||
#error "Asm thunk not implemeted for this architecture!"
|
#error "Asm thunk not implemeted for this architecture!"
|
||||||
|
@ -135,7 +136,7 @@ struct tag_CallbackThunk
|
||||||
// Free() only knows about pNext in CallbackThunk, it does not know anything about the assembly, that is where this helper comes in...
|
// Free() only knows about pNext in CallbackThunk, it does not know anything about the assembly, that is where this helper comes in...
|
||||||
#ifdef SYSTEM_X86
|
#ifdef SYSTEM_X86
|
||||||
# define GetAssociatedSysProcFromCallbackThunkPtr(pCbT) ( (SystemProc*) *(unsigned int*) (((char*)(pCbT))+1) )
|
# define GetAssociatedSysProcFromCallbackThunkPtr(pCbT) ( (SystemProc*) *(unsigned int*) (((char*)(pCbT))+1) )
|
||||||
#elif defined(SYSTEM_X64)
|
#elif defined(SYSTEM_AMD64)
|
||||||
# define GetAssociatedSysProcFromCallbackThunkPtr(pCbT) BUGBUG64(NULL)
|
# define GetAssociatedSysProcFromCallbackThunkPtr(pCbT) BUGBUG64(NULL)
|
||||||
#else
|
#else
|
||||||
# error "GetAssociatedSysProcFromCallbackThunkPtr not defined for the current architecture!"
|
# error "GetAssociatedSysProcFromCallbackThunkPtr not defined for the current architecture!"
|
||||||
|
@ -145,14 +146,23 @@ struct tag_CallbackThunk
|
||||||
extern const int ParamSizeByType[]; // Size of every parameter type (*4 bytes)
|
extern const int ParamSizeByType[]; // Size of every parameter type (*4 bytes)
|
||||||
|
|
||||||
extern HANDLE CreateCallback(SystemProc *cbproc);
|
extern HANDLE CreateCallback(SystemProc *cbproc);
|
||||||
extern SystemProc *PrepareProc(BOOL NeedForCall);
|
extern SystemProc* PrepareProc(BOOL NeedForCall);
|
||||||
extern void ParamAllocate(SystemProc *proc);
|
extern void ParamAllocate(SystemProc *proc);
|
||||||
extern void ParamsDeAllocate(SystemProc *proc);
|
extern void ParamsDeAllocate(SystemProc *proc);
|
||||||
extern void ParamsIn(SystemProc *proc);
|
extern void ParamsIn(SystemProc *proc);
|
||||||
extern void ParamsOut(SystemProc *proc);
|
extern void ParamsOut(SystemProc *proc);
|
||||||
extern SystemProc *CallProc(SystemProc *proc);
|
#ifdef SYSTEM_AMD64
|
||||||
extern SystemProc *CallBack(SystemProc *proc);
|
#ifdef SYSTEM_PARTIALCALLSUPPORT
|
||||||
extern SystemProc *RealCallBack();
|
extern SystemProc* CallProc2(SystemProc *proc, UINT_PTR ParamCount);
|
||||||
|
#define CallProc(p) CallProc2((p), (p)->ParamCount) // ParamCount is passed as a parameter so CallProc2 can determine the required stack size without a function call
|
||||||
|
#endif
|
||||||
|
#else // !SYSTEM_AMD64
|
||||||
|
extern SystemProc* CallProc(SystemProc *proc);
|
||||||
|
#endif // ~SYSTEM_AMD64
|
||||||
|
#ifndef SYSTEM_NOCALLBACKS
|
||||||
|
extern SystemProc* CallBack(SystemProc *proc);
|
||||||
|
extern SystemProc* RealCallBack();
|
||||||
|
#endif
|
||||||
extern void CallStruct(SystemProc *proc);
|
extern void CallStruct(SystemProc *proc);
|
||||||
|
|
||||||
#ifdef _UNICODE
|
#ifdef _UNICODE
|
||||||
|
|
|
@ -422,7 +422,7 @@ System::Free $0
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<ul>
|
<ul>
|
||||||
<li>To find out the index of a member in a COM interface, you need to search for the definition of this COM interface in the header files that come with Visual C/C++ or the Platform SDK. Remember the index is zero based.</li>
|
<li>To find out the index of a member in a COM interface, you need to search for the definition of this COM interface in the header files that come with Visual C/C++ or the Platform SDK. Remember the index is zero based.</li>
|
||||||
<li>If a function can't be found, an `A' will be appended to its name and it will be looked up again. This is done because a lot of Windows API functions have two versions, one for ANSI strings and one for Unicode strings. The ANSI version of the function is marked with `A' and the Unicode version is marked with `W'. For example: lstrcpyA and lstrcpyW.</li>
|
<li>If a function can't be found or the <code>t</code> parameter type was used, an `A' or `W' will be appended to its name and it will be looked up again. This is done because a lot of Windows API functions have two versions, one for ANSI strings and one for Unicode strings. The ANSI version of the function is marked with `A' and the Unicode version is marked with `W'. For example: lstrcpyA and lstrcpyW.</li>
|
||||||
</ul>
|
</ul>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
|
|
||||||
|
@ -436,7 +436,7 @@ System::Free $0
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>c</th>
|
<th>c</th>
|
||||||
<td>cdecl calling convention (the stack restored by caller). By default stdcall calling convention is used (the stack restored by callee).</td>
|
<td>cdecl calling convention (the stack restored by caller). By default stdcall calling convention is used on x86 (the stack restored by callee).</td>
|
||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
|
|
@ -6,6 +6,12 @@ Released on ?, 2014
|
||||||
|
|
||||||
\S1{v3.0b0-rl} Release Notes
|
\S1{v3.0b0-rl} Release Notes
|
||||||
|
|
||||||
|
\S1{v3.0b0-cl} Changelog
|
||||||
|
|
||||||
|
\S2{} Major Changes
|
||||||
|
|
||||||
|
\b Basic AMD64 System::Call support
|
||||||
|
|
||||||
\S2{} Minor Changes
|
\S2{} Minor Changes
|
||||||
|
|
||||||
\b Added Int<32|64|Ptr><Op|Cmp[U]> helper macros to Util.nsh
|
\b Added Int<32|64|Ptr><Op|Cmp[U]> helper macros to Util.nsh
|
||||||
|
|
|
@ -45,7 +45,8 @@ defenv.Append(CPPDEFINES = [('NSISCALL', '$STDCALL')])
|
||||||
|
|
||||||
### asm
|
### asm
|
||||||
|
|
||||||
defenv.Append(ASFLAGS = ['/coff'])
|
if 'x86' in defenv.get('TARGET_ARCH','x86'):
|
||||||
|
defenv.Append(ASFLAGS = ['/coff']) # ML64 does not support /coff
|
||||||
|
|
||||||
### debug
|
### debug
|
||||||
|
|
||||||
|
|
|
@ -287,9 +287,10 @@ def generate(env):
|
||||||
|
|
||||||
|
|
||||||
include_path, lib_path, exe_path, sdk_path = "", "", "", ""
|
include_path, lib_path, exe_path, sdk_path = "", "", "", ""
|
||||||
|
targ_arc = env.get('TARGET_ARCH', 'x86')
|
||||||
|
|
||||||
if os.environ.has_key('MSVC_USE_SCRIPT') and "None" == os.environ['MSVC_USE_SCRIPT']:
|
if os.environ.has_key('MSVC_USE_SCRIPT') and "None" == os.environ['MSVC_USE_SCRIPT']:
|
||||||
for x in ['INCLUDE', 'LIB', 'PATH']: env['ENV'][x] = ""
|
for x in ['INCLUDE', 'LIB', 'PATH', 'CL', 'LINK', 'ML']: env['ENV'][x] = ""
|
||||||
if not env.WhereIs('cl', os.environ['PATH']):
|
if not env.WhereIs('cl', os.environ['PATH']):
|
||||||
raise SCons.Errors.InternalError("CL not found in %s" % os.environ['PATH'])
|
raise SCons.Errors.InternalError("CL not found in %s" % os.environ['PATH'])
|
||||||
include_path = os.environ['INCLUDE']
|
include_path = os.environ['INCLUDE']
|
||||||
|
@ -309,8 +310,8 @@ def generate(env):
|
||||||
env.PrependENVPath('INCLUDE', include_path)
|
env.PrependENVPath('INCLUDE', include_path)
|
||||||
env.PrependENVPath('LIB', lib_path)
|
env.PrependENVPath('LIB', lib_path)
|
||||||
env.PrependENVPath('PATH', exe_path)
|
env.PrependENVPath('PATH', exe_path)
|
||||||
|
|
||||||
env['ENV']['CPU'] = 'i386' # TODO: Check TARGET_ARCH for AMD64
|
env['ENV']['CPU'] = (targ_arc.upper(), 'i386')['x86' in targ_arc.lower()] # i386 or AMD64
|
||||||
env['ENV']['TARGETOS'] = 'BOTH'
|
env['ENV']['TARGETOS'] = 'BOTH'
|
||||||
env['ENV']['APPVER'] = '4.0'
|
env['ENV']['APPVER'] = '4.0'
|
||||||
env['ENV']['MSSDK'] = sdk_path
|
env['ENV']['MSSDK'] = sdk_path
|
||||||
|
@ -319,7 +320,7 @@ def generate(env):
|
||||||
env['ENV']['INETSDK'] = sdk_path
|
env['ENV']['INETSDK'] = sdk_path
|
||||||
env['ENV']['MSSDK'] = sdk_path
|
env['ENV']['MSSDK'] = sdk_path
|
||||||
env['ENV']['MSTOOLS'] = sdk_path
|
env['ENV']['MSTOOLS'] = sdk_path
|
||||||
|
|
||||||
env['CFILESUFFIX'] = '.c'
|
env['CFILESUFFIX'] = '.c'
|
||||||
env['CXXFILESUFFIX'] = '.cc'
|
env['CXXFILESUFFIX'] = '.cc'
|
||||||
|
|
||||||
|
@ -329,7 +330,10 @@ def generate(env):
|
||||||
env['AR'] = '"' + sdk_path_AR + '"'
|
env['AR'] = '"' + sdk_path_AR + '"'
|
||||||
env['ARFLAGS'] = SCons.Util.CLVar('/nologo')
|
env['ARFLAGS'] = SCons.Util.CLVar('/nologo')
|
||||||
env['ARCOM'] = "${TEMPFILE('$AR $ARFLAGS /OUT:$TARGET $SOURCES')}"
|
env['ARCOM'] = "${TEMPFILE('$AR $ARFLAGS /OUT:$TARGET $SOURCES')}"
|
||||||
|
|
||||||
|
if 'AMD64' in targ_arc.upper():
|
||||||
|
env['AS'] = 'ml64'
|
||||||
|
|
||||||
env['SHLINK'] = '$LINK'
|
env['SHLINK'] = '$LINK'
|
||||||
env['SHLINKFLAGS'] = SCons.Util.CLVar('$LINKFLAGS /dll')
|
env['SHLINKFLAGS'] = SCons.Util.CLVar('$LINKFLAGS /dll')
|
||||||
env['_SHLINK_TARGETS'] = win32ShlinkTargets
|
env['_SHLINK_TARGETS'] = win32ShlinkTargets
|
||||||
|
|
|
@ -1056,11 +1056,11 @@ static INT_PTR CALLBACK DirProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM l
|
||||||
{
|
{
|
||||||
BOOL (WINAPI *GDFSE)(LPCTSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER) =
|
BOOL (WINAPI *GDFSE)(LPCTSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER) =
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
GetDiskFreeSpaceEx;
|
GetDiskFreeSpaceEx;
|
||||||
#else
|
#else
|
||||||
myGetProcAddress(MGA_GetDiskFreeSpaceEx);
|
myGetProcAddress(MGA_GetDiskFreeSpaceEx);
|
||||||
#endif
|
|
||||||
if (GDFSE)
|
if (GDFSE)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
ULARGE_INTEGER available64;
|
ULARGE_INTEGER available64;
|
||||||
ULARGE_INTEGER a, b;
|
ULARGE_INTEGER a, b;
|
||||||
|
@ -1093,7 +1093,7 @@ static INT_PTR CALLBACK DirProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM l
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!available_set) // TODO: Can GetDiskFreeSpace succeed when ..Ex failed on x64?
|
if (!available_set && sizeof(void*) <= 4)
|
||||||
{
|
{
|
||||||
DWORD spc, bps, fc, tc;
|
DWORD spc, bps, fc, tc;
|
||||||
TCHAR *root;
|
TCHAR *root;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue