Initial groundwork for ARM64 support
git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@7001 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
parent
bca384e691
commit
460b3f59a9
11 changed files with 101 additions and 51 deletions
|
@ -191,7 +191,9 @@ extern "C" BOOL APIENTRY DllMain(HINSTANCE _hModule, DWORD ul_reason_for_call,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
#ifndef INT32_MAX
|
||||
#define INT32_MAX 0x7fffffff
|
||||
#endif
|
||||
|
||||
int MulDiv64(int nNumber, __int64 nNumerator, __int64 nDenominator)
|
||||
{
|
||||
|
|
|
@ -77,13 +77,18 @@ void myitoa64(__int64 i, char *buffer)
|
|||
// Visual Studio 2015 (CLv19 x86) and some older versions of CLv14 x64 will optimize
|
||||
// our loop into a direct call to _memset and this fails to link because we don't use the CRT
|
||||
#if defined(_MSC_VER) && _MSC_VER+0 >= 1400
|
||||
#if defined(_MSC_FULL_VER) && _MSC_FULL_VER+0 >= 140050727
|
||||
#include <intrin.h>
|
||||
#else
|
||||
EXTERN_C void __stosb(BYTE*,BYTE,size_t);
|
||||
#endif //~ _MSC_FULL_VER >= 140050727
|
||||
#pragma intrinsic(__stosb)
|
||||
#define CRTINTRINSIC_memset(p,c,s) __stosb((BYTE*)(p),(BYTE)(c),(s))
|
||||
# if defined(_MSC_FULL_VER) && _MSC_FULL_VER+0 >= 140050727
|
||||
# include <intrin.h>
|
||||
# else
|
||||
EXTERN_C void __stosb(BYTE*,BYTE,size_t);
|
||||
# endif //~ _MSC_FULL_VER >= 140050727
|
||||
# if defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) // __stosb not available under _M_ARM nor _M_ARM64
|
||||
# pragma intrinsic(__stosb)
|
||||
# define CRTINTRINSIC_memset(p,c,s) __stosb((BYTE*)(p),(BYTE)(c),(s))
|
||||
# elif defined(_M_ARM) || defined(_M_ARM64) // For _MSC_VER=1914 (VS 15.7.27703.2026/CL 19.14.26430)
|
||||
EXTERN_C void* __cdecl memset(void *d, int v, size_t l) { char *p=(char*)d; while (l-- > 0) *p++=v; return d; }
|
||||
# pragma function(memset)
|
||||
# endif
|
||||
#endif //~ _MSC_VER
|
||||
|
||||
void mini_memset(void *o,char i,int l)
|
||||
|
|
|
@ -289,6 +289,32 @@ PLUGINFUNCTION(Get)
|
|||
} PLUGINFUNCTIONEND
|
||||
|
||||
|
||||
#ifdef SYSTEM_ARM64
|
||||
/*
|
||||
TODO: CallProc not implemeted.
|
||||
Fake the behavior of the System plugin for the LoadImage API function so MUI works.
|
||||
BUGBUG: MUI is leaking DeleteObject and failing GetClientRect
|
||||
*/
|
||||
SystemProc* CallProc(SystemProc *proc)
|
||||
{
|
||||
INT_PTR ret, *place;
|
||||
int cmp = lstrcmp(proc->ProcName, sizeof(TCHAR) > 1 ? _T("LoadImageW") : _T("LoadImageA"));
|
||||
if (!cmp)
|
||||
{
|
||||
ret = (INT_PTR) LoadImage((HINSTANCE)proc->Params[1].Value,
|
||||
(LPCTSTR)proc->Params[2].Value, (UINT)proc->Params[3].Value,
|
||||
(int)proc->Params[4].Value, (int)proc->Params[5].Value,
|
||||
(UINT)proc->Params[6].Value);
|
||||
LastError = GetLastError();
|
||||
}
|
||||
else
|
||||
proc->ProcResult = PR_ERROR, ret = 0, LastError = ERROR_INVALID_FUNCTION;
|
||||
place = (INT_PTR*) proc->Params[0].Value;
|
||||
if (proc->Params[0].Option != -1) place = (INT_PTR*) &(proc->Params[0].Value);
|
||||
if (place) *place = ret;
|
||||
return proc;
|
||||
}
|
||||
#endif //~ SYSTEM_ARM64
|
||||
#ifdef _WIN64
|
||||
/*
|
||||
BUGBUG: TODO: CallBack support not implemeted!
|
||||
|
@ -1158,7 +1184,7 @@ void ParamsOut(SystemProc *proc)
|
|||
|
||||
HANDLE CreateCallback(SystemProc *cbproc)
|
||||
{
|
||||
#ifdef SYSTEM_AMD64
|
||||
#if defined(SYSTEM_AMD64) || defined(SYSTEM_ARM64)
|
||||
return BUGBUG64(HANDLE) NULL;
|
||||
#else
|
||||
char *mem;
|
||||
|
@ -1357,7 +1383,7 @@ BOOL WINAPI DllMain(HINSTANCE hInst, DWORD fdwReason, LPVOID lpReserved)
|
|||
#ifdef SYSTEM_X86
|
||||
retexpr[0] = (char) 0xC2;
|
||||
retexpr[2] = 0x00;
|
||||
#elif defined(SYSTEM_AMD64)
|
||||
#elif defined(SYSTEM_AMD64) || defined(SYSTEM_ARM64)
|
||||
retexpr[0] = BUGBUG64(0);
|
||||
#else
|
||||
#error TODO
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
# define SYSTEM_AMD64
|
||||
#elif defined(_M_IX86) || defined(__i386__) || defined(_X86_)
|
||||
# define SYSTEM_X86
|
||||
#elif defined(_M_ARM64)
|
||||
# define SYSTEM_ARM64
|
||||
#else
|
||||
# error "Unknown architecture!"
|
||||
#endif
|
||||
|
@ -147,7 +149,7 @@ struct tag_CallbackThunk
|
|||
#pragma pack(pop)
|
||||
*/
|
||||
char asm_code[10];
|
||||
#elif defined(SYSTEM_AMD64)
|
||||
#elif defined(SYSTEM_AMD64) || defined(SYSTEM_ARM64)
|
||||
char asm_code[BUGBUG64(1)]; // TODO: BUGBUG64
|
||||
#else
|
||||
#error "Asm thunk not implemeted for this architecture!"
|
||||
|
@ -159,7 +161,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...
|
||||
#ifdef SYSTEM_X86
|
||||
# define GetAssociatedSysProcFromCallbackThunkPtr(pCbT) ( (SystemProc*) *(unsigned int*) (((char*)(pCbT))+1) )
|
||||
#elif defined(SYSTEM_AMD64)
|
||||
#elif defined(SYSTEM_AMD64) || defined(SYSTEM_ARM64)
|
||||
# define GetAssociatedSysProcFromCallbackThunkPtr(pCbT) BUGBUG64(NULL)
|
||||
#else
|
||||
# error "GetAssociatedSysProcFromCallbackThunkPtr not defined for the current architecture!"
|
||||
|
|
|
@ -144,8 +144,8 @@ stub_env.Append(LINKFLAGS = ['$NODEFLIBS_FLAG']) # no default libraries
|
|||
stub_env.Append(LINKFLAGS = ['$MAP_FLAG']) # generate map file
|
||||
|
||||
if msvs_version >= 10.0:
|
||||
# no relocations that our resource editor ignores
|
||||
stub_env.Append(LINKFLAGS = ['/FIXED'])
|
||||
if stub_env['TARGET_ARCH'] != 'arm64': # LNK1246: '/FIXED' not compatible with 'ARM64' target machine
|
||||
stub_env.Append(LINKFLAGS = ['/FIXED']) # no relocations that our resource editor ignores
|
||||
|
||||
stub_uenv = stub_env.Clone()
|
||||
stub_uenv.Append(CPPDEFINES = ['_UNICODE', 'UNICODE'])
|
||||
|
|
|
@ -313,7 +313,7 @@ def generate(env):
|
|||
env.PrependENVPath('LIB', lib_path)
|
||||
env.PrependENVPath('PATH', exe_path)
|
||||
|
||||
env['ENV']['CPU'] = (targ_arc.upper(), 'i386')['x86' in targ_arc.lower()] # i386 or AMD64
|
||||
env['ENV']['CPU'] = (targ_arc.upper(), 'i386')['x86' in targ_arc.lower()] # AMD64/ARM64 or i386
|
||||
env['ENV']['TARGETOS'] = 'BOTH'
|
||||
env['ENV']['APPVER'] = '4.0'
|
||||
env['ENV']['MSSDK'] = sdk_path
|
||||
|
@ -340,6 +340,8 @@ def generate(env):
|
|||
|
||||
if 'AMD64' in targ_arc.upper():
|
||||
env['AS'] = 'ml64'
|
||||
if 'ARM64' in targ_arc.upper():
|
||||
env['AS'] = 'armasm64'
|
||||
|
||||
env['SHLINK'] = '$LINK'
|
||||
env['SHLINKFLAGS'] = SCons.Util.CLVar('$LINKFLAGS /dll')
|
||||
|
|
|
@ -175,6 +175,8 @@ class MSPE:
|
|||
self.NTHOffset = fanew
|
||||
self.NTOHMagic = ReadU16LE(f, fanew+4+20)
|
||||
self.IsPEP = 0x20b == self.NTOHMagic # IMAGE_NT_OPTIONAL_HDR64_MAGIC?
|
||||
def ReadMachine(self):
|
||||
return ReadU16LE(self._f, self.NTHOffset+4+0)
|
||||
def ReadCharacteristics(self):
|
||||
return ReadU16LE(self._f, self.NTHOffset+4+18)
|
||||
def WriteCharacteristics(self, value):
|
||||
|
@ -202,7 +204,8 @@ def SetPESecurityFlagsWorker(filepath):
|
|||
pe.WriteCharacteristics(ifh_c)
|
||||
ioh_dc = pe.ReadDllCharacteristics()
|
||||
ioh_dc |= 0x0100 # +IMAGE_DLLCHARACTERISTICS_NX_COMPAT (DEP)
|
||||
ioh_dc |= 0x0400 # +IMAGE_DLLCHARACTERISTICS_NO_SEH
|
||||
if pe.ReadMachine() != 0xaa64: # ARM64 forces exception directory?
|
||||
ioh_dc |= 0x0400 # +IMAGE_DLLCHARACTERISTICS_NO_SEH
|
||||
ioh_dc |= 0x8000 # +IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE (TODO: Should we set this on .DLLs?)
|
||||
if not (ifh_c & 0x0001): # IMAGE_FILE_RELOCS_STRIPPED?
|
||||
ioh_dc |= 0x0040 # +IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE (ASLR)
|
||||
|
|
32
SConstruct
32
SConstruct
|
@ -171,7 +171,7 @@ opts.Add(('PATH', 'A colon-separated list of system paths instead of the default
|
|||
opts.Add(('TOOLSET', 'A comma-separated list of specific tools used for building instead of the default', None))
|
||||
opts.Add(BoolVariable('MSTOOLKIT', 'Use Microsoft Visual C++ Toolkit', 'no'))
|
||||
opts.Add(EnumVariable('MSVS_VERSION', 'MS Visual C++ version', os.environ.get('MSVS_VERSION'), allowed_values=('6.0', '7.0', '7.1', '8.0', '8.0Exp', '9.0', '9.0Exp', '10.0', '10.0Exp')))
|
||||
opts.Add(EnumVariable('TARGET_ARCH', 'Target processor architecture', 'x86', allowed_values=('x86', 'amd64')))
|
||||
opts.Add(EnumVariable('TARGET_ARCH', 'Target processor architecture', 'x86', allowed_values=('x86', 'amd64', 'arm64')))
|
||||
opts.Add(ListVariable('DOCTYPES', 'A list of document types that will be built', default_doctype, doctypes))
|
||||
opts.Add(('CC', 'Override C compiler', None))
|
||||
opts.Add(('CXX', 'Override C++ compiler', None))
|
||||
|
@ -285,6 +285,19 @@ f.close()
|
|||
####### Common Functions ###
|
||||
######################################################################
|
||||
|
||||
def GetArcCPU(env):
|
||||
if (not env.has_key('TARGET_ARCH')) or env['TARGET_ARCH'] == 'x86':
|
||||
return 'x86'
|
||||
return env['TARGET_ARCH']
|
||||
|
||||
def GetArcSuffix(env, unicode = None):
|
||||
if unicode is None:
|
||||
unicode = 'UNICODE' in env['CPPDEFINES']
|
||||
suff = '-unicode'
|
||||
if not unicode:
|
||||
suff = '-ansi'
|
||||
return GetArcCPU(env) + suff
|
||||
|
||||
def SafeFile(f):
|
||||
from types import StringType
|
||||
|
||||
|
@ -334,8 +347,8 @@ defenv['INSTDISTDIR'] = defenv.Dir('#.instdist')
|
|||
defenv['TESTDISTDIR'] = defenv.Dir('#.test')
|
||||
defenv['DISTSUFFIX'] = ''
|
||||
|
||||
if defenv['TARGET_ARCH'] == 'amd64':
|
||||
defenv['DISTSUFFIX'] += '-amd64'
|
||||
if GetArcCPU(defenv) != 'x86':
|
||||
defenv['DISTSUFFIX'] += GetArcCPU(defenv)
|
||||
if defenv.has_key('CODESIGNER'):
|
||||
defenv['DISTSUFFIX'] += '-signed'
|
||||
|
||||
|
@ -525,19 +538,6 @@ plugin_uenv = envs[7]
|
|||
|
||||
Export('plugin_env plugin_uenv')
|
||||
|
||||
def GetArcCPU(env):
|
||||
if (not env.has_key('TARGET_ARCH')) or env['TARGET_ARCH'] == 'x86':
|
||||
return 'x86'
|
||||
return env['TARGET_ARCH']
|
||||
|
||||
def GetArcSuffix(env, unicode = None):
|
||||
if unicode is None:
|
||||
unicode = 'UNICODE' in env['CPPDEFINES']
|
||||
suff = '-unicode'
|
||||
if not unicode:
|
||||
suff = '-ansi'
|
||||
return GetArcCPU(env) + suff
|
||||
|
||||
######################################################################
|
||||
####### Distribution ###
|
||||
######################################################################
|
||||
|
|
|
@ -136,6 +136,9 @@ CEXEBuild::CEXEBuild(signed char pponly, bool warnaserror) :
|
|||
m_target_type=TARGET_X86ANSI;
|
||||
#ifdef _WIN32
|
||||
if (sizeof(void*) > 4) m_target_type = TARGET_AMD64; // BUGBUG: scons 'TARGET_ARCH' should specify the default
|
||||
#endif
|
||||
#ifdef _M_ARM64
|
||||
m_target_type = TARGET_ARM64; // BUGBUG: scons 'TARGET_ARCH' should specify the default
|
||||
#endif
|
||||
build_unicode=TARGET_X86ANSI != m_target_type;
|
||||
build_lockedunicodetarget=false;
|
||||
|
@ -3880,19 +3883,36 @@ int CEXEBuild::set_target_architecture_data()
|
|||
}
|
||||
definedlist.set(_T("NSIS_PTR_SIZE"), is_target_64bit() ? _T("8") : _T("4"));
|
||||
|
||||
tstring cpu = get_string_prefix(get_target_suffix(m_target_type), _T("-"));
|
||||
const TCHAR* tsuff = get_target_suffix(m_target_type, _T(""));
|
||||
if (!*tsuff) return PS_ERROR;
|
||||
tstring cpu = get_string_prefix(tsuff, _T("-"));
|
||||
definedlist.set(_T("NSIS_CPU"), cpu.c_str()); // Used by Library.nsh to pick the correct RegTool
|
||||
|
||||
definedlist.del(_T("NSIS_IX86"));
|
||||
definedlist.del(_T("NSIS_AMD64"));
|
||||
if (TARGET_AMD64 == m_target_type)
|
||||
definedlist.set(_T("NSIS_AMD64"));
|
||||
else
|
||||
definedlist.set(_T("NSIS_IX86"), build_unicode ? _T("400") : _T("300"));
|
||||
struct { TARGETTYPE tt; const TCHAR *def; const TCHAR *val; } static const tdef[] = {
|
||||
{ TARGET_X86ANSI, _T("NSIS_IX86"), _T("300") },
|
||||
{ TARGET_X86UNICODE, _T("NSIS_IX86"), _T("400") },
|
||||
{ TARGET_AMD64, _T("NSIS_AMD64"), _T("1") },
|
||||
{ TARGET_ARM64, _T("NSIS_ARM64"), _T("1") }
|
||||
};
|
||||
size_t i;
|
||||
for (i = 0; i < COUNTOF(tdef); ++i) definedlist.del(tdef[i].def);
|
||||
for (i = 0; i < COUNTOF(tdef); ++i) if (tdef[i].tt == m_target_type) definedlist.set(tdef[i].def, tdef[i].val);
|
||||
|
||||
return PS_OK;
|
||||
}
|
||||
|
||||
const TCHAR* CEXEBuild::get_target_suffix(CEXEBuild::TARGETTYPE tt, const TCHAR*defval) const
|
||||
{
|
||||
switch(tt)
|
||||
{
|
||||
case TARGET_X86ANSI : return _T("x86-ansi");
|
||||
case TARGET_X86UNICODE: return _T("x86-unicode");
|
||||
case TARGET_AMD64 : return _T("amd64-unicode");
|
||||
case TARGET_ARM64 : return _T("arm64-unicode");
|
||||
default: return defval;
|
||||
}
|
||||
}
|
||||
|
||||
int CEXEBuild::change_target_architecture(TARGETTYPE tt)
|
||||
{
|
||||
const bool wide = TARGET_X86ANSI != tt;
|
||||
|
@ -3932,17 +3952,6 @@ CEXEBuild::TARGETTYPE CEXEBuild::get_target_type(const TCHAR*s) const
|
|||
return TARGET_UNKNOWN;
|
||||
}
|
||||
|
||||
const TCHAR* CEXEBuild::get_target_suffix(CEXEBuild::TARGETTYPE tt, const TCHAR*defval) const
|
||||
{
|
||||
switch(tt)
|
||||
{
|
||||
case TARGET_X86ANSI : return _T("x86-ansi");
|
||||
case TARGET_X86UNICODE: return _T("x86-unicode");
|
||||
case TARGET_AMD64 : return _T("amd64-unicode");
|
||||
default: return defval;
|
||||
}
|
||||
}
|
||||
|
||||
void CEXEBuild::print_bad_targettype_parameter(const TCHAR*cmdname, const TCHAR*prefix) const
|
||||
{
|
||||
tstring errstr = cmdname;
|
||||
|
|
|
@ -230,6 +230,7 @@ class CEXEBuild {
|
|||
TARGET_X86ANSI = TARGETFIRST,
|
||||
TARGET_X86UNICODE,
|
||||
TARGET_AMD64, // Always Unicode
|
||||
TARGET_ARM64, // Always Unicode
|
||||
TARGET_UNKNOWN,
|
||||
TARGETCOUNT = (TARGET_UNKNOWN-TARGETFIRST)
|
||||
} TARGETTYPE;
|
||||
|
@ -238,7 +239,7 @@ class CEXEBuild {
|
|||
bool m_previous_x86_unicode;
|
||||
const TCHAR* get_target_suffix(CEXEBuild::TARGETTYPE tt, const TCHAR*defval = _T("?")) const;
|
||||
const TCHAR* get_target_suffix() const { return get_target_suffix(m_target_type); }
|
||||
static bool is_targettype_64bit(TARGETTYPE tt) { return TARGET_AMD64 == tt; }
|
||||
static bool is_targettype_64bit(TARGETTYPE tt) { return TARGET_AMD64 == tt || TARGET_ARM64 == tt; }
|
||||
bool is_target_64bit() const { return is_targettype_64bit(m_target_type); }
|
||||
void print_bad_targettype_parameter(const TCHAR*cmdname, const TCHAR*prefix = _T("")) const;
|
||||
unsigned int get_header_size() const { return (unsigned int)sizeof(header) + (is_target_64bit() ? (4 * BLOCKS_NUM) : 0); }
|
||||
|
|
|
@ -876,7 +876,7 @@ int CEXEBuild::process_jump(LineParser &line, int wt, int *offs)
|
|||
#define SECTION_FIELD_GET(field) (FIELD_OFFSET(section, field)/sizeof(int))
|
||||
#define SECTION_FIELD_SET(field) (-1 - (int)(FIELD_OFFSET(section, field)/sizeof(int)))
|
||||
|
||||
#define INVALIDREGROOT ( (HKEY) 0x8000baad )
|
||||
#define INVALIDREGROOT ( (HKEY) (UINT_PTR) 0x8000baad )
|
||||
static HKEY ParseRegRootKey(LineParser &line, int tok)
|
||||
{
|
||||
static const TCHAR *rootkeys[2] = {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue