From e0dba40bc6981e4952f63c35883b83899a68c3d3 Mon Sep 17 00:00:00 2001 From: slipher Date: Sat, 27 Jun 2026 17:58:31 -0500 Subject: [PATCH 01/11] Migrate a removed scons API (has_key) --- site_scons/site_tools/naclsdk.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site_scons/site_tools/naclsdk.py b/site_scons/site_tools/naclsdk.py index 10159a4566..b0f5747d93 100755 --- a/site_scons/site_tools/naclsdk.py +++ b/site_scons/site_tools/naclsdk.py @@ -553,7 +553,7 @@ def __call__(self, target, source, env, for_signature): # Default to the .lnk suffix for the benefit of the Phar Lap # linkloc linker, which likes to append an .lnk suffix if # none is given. - if env.has_key('TEMPFILESUFFIX'): + if 'TEMPFILESUFFIX' in env: suffix = env.subst('$TEMPFILESUFFIX') else: suffix = '.lnk' From 5807708a20e5d3db598a3cc68e1866b3c58b8f80 Mon Sep 17 00:00:00 2001 From: slipher Date: Fri, 26 Jun 2026 20:31:51 -0500 Subject: [PATCH 02/11] Partially revert "Enable Scons builds on Win10" This reverts commit 1d34ecb7cdd1e5b295ac107107abc09b22e866d8. That commit made it so that MSVC builds could only be done on Google's build bot. DEPS and buildbot/ changes were left out the revert. buildbot/ is not used by us and has a conflict. --- .../site_tools/target_platform_windows.py | 46 ------------------- 1 file changed, 46 deletions(-) diff --git a/site_scons/site_tools/target_platform_windows.py b/site_scons/site_tools/target_platform_windows.py index 1d921e7f9c..6d1954f2a5 100755 --- a/site_scons/site_tools/target_platform_windows.py +++ b/site_scons/site_tools/target_platform_windows.py @@ -14,7 +14,6 @@ from __future__ import print_function -import json import os import time import SCons.Script @@ -235,22 +234,6 @@ def _CoverageInstall(dest, source, env): else: env['PRECOVERAGE_INSTALL'](dest, source, env) -def _FindDepotTools(): - paths = os.environ['PATH'].split(os.pathsep) - for path in paths: - if os.path.split(path)[-1] == 'depot_tools': - return path - raise Exception('Cannot find depot_tools in PATH!') - - -def _FindVSFilesPath(): - vs = os.path.join(_FindDepotTools(), 'win_toolchain', 'vs_files') - for version in os.listdir(vs): - path = os.path.join(vs, version) - if os.path.exists(os.path.join(path, 'Windows Kits')): - return path - raise Exception('Cannot find MSVC in depot_tools!') - def generate(env): # NOTE: SCons requires the use of this name, which fails gpylint. @@ -278,35 +261,6 @@ def generate(env): # Load various Visual Studio related tools. if use_msvc_tools: - # Our bots have a file that encodes necessary environment vars in a .json - # file. Find it, read it, and set ENVs accordingly. - vs_files_path = _FindVSFilesPath() - env_json_file = os.path.join(vs_files_path, 'Windows Kits', - '10', 'bin', 'SetEnv.x64.json') - if not os.path.exists(env_json_file): - raise Exception('Could not find environment file for MSVC!') - - with open(env_json_file) as f: - parsed_json_env = json.load(f)['env'] - - # Example keys: INCLUDE, LIB, PATH, LIBPATH - for key, paths in parsed_json_env.items(): - for path in paths: - final_path = os.path.join(vs_files_path, *path) - env.AppendENVPath(key, final_path) - - # VS autodetection relies on vswhere.exe, which our bots don't have. - # Disable VS autodetection by setting MSVC_USE_SCRIPT to False, and set - # location and version directly. - env['MSVC_USE_SCRIPT'] = False - env['MSSDK_DIR'] = vs_files_path - # If this gets updated, we may also need to update scons, as this is the - # newest version that our scons knows about. - # VS_VERSION 2022 will be MSVC_VERSION 14.3 - with open(os.path.join(vs_files_path, 'VS_VERSION')) as f: - assert f.read().strip() == '2019' - env['MSVC_VERSION'] = '14.2' - env.Tool('as') env.Tool('msvs') env.Tool('windows_hard_link') From c73a3705285fa6324aa06d89e4c62bd2b75d3ddd Mon Sep 17 00:00:00 2001 From: slipher Date: Mon, 29 Jun 2026 16:11:31 -0500 Subject: [PATCH 03/11] Don't use some GCC/Clang flags on MSVC --- src/shared/platform/build.scons | 6 ++++-- src/trusted/nacl_base/build.scons | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/shared/platform/build.scons b/src/shared/platform/build.scons index 16810196cc..91a246feb5 100644 --- a/src/shared/platform/build.scons +++ b/src/shared/platform/build.scons @@ -9,8 +9,10 @@ import os import platform Import('env') -env.Append(CCFLAGS=['-Wno-cast-function-type-mismatch', - '-Wno-unknown-warning-option']) + +if not env.Bit('windows'): # FIXME: better MSVC test + env.Append(CCFLAGS=['-Wno-cast-function-type-mismatch', + '-Wno-unknown-warning-option']) platform_inputs = [] diff --git a/src/trusted/nacl_base/build.scons b/src/trusted/nacl_base/build.scons index e6b85b573c..18d4dfa4b2 100644 --- a/src/trusted/nacl_base/build.scons +++ b/src/trusted/nacl_base/build.scons @@ -13,7 +13,8 @@ if env.Bit('built_elsewhere'): # Modern compilers detect that the NACL_ASSERT_IS_POINTER(x) macro does not # actually use x, which can trigger false warnings. -env.Append(CCFLAGS='-Wno-unused-but-set-variable') +if not env.Bit('windows'): # FIXME: better MSVC test + env.Append(CCFLAGS='-Wno-unused-but-set-variable') nacl_base_lib_inputs = [ 'nacl_refcount.c', From 2d06b944d44ef86b8491942045316ac13e613df2 Mon Sep 17 00:00:00 2001 From: slipher Date: Sun, 28 Jun 2026 17:55:57 -0500 Subject: [PATCH 04/11] scons: Implement werror=0 for Windows Now I can build the loader and IRT with VS 2022, and external SCons (with pywin32 module installed), e.g. scons.exe platform=x86-64 saigo=1 werror=0 --no-clang --mode=opt-host,nacl irt_core sel_ldr --- SConstruct | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/SConstruct b/SConstruct index cf2aca4857..44eaddb7d9 100755 --- a/SConstruct +++ b/SConstruct @@ -2335,8 +2335,10 @@ def MakeWindowsEnv(platform=None): LIBS = ['ws2_32', 'advapi32'], # TODO(bsy) remove 4355 once cross-repo # NACL_ALLOW_THIS_IN_INITIALIZER_LIST changes go in. - CCFLAGS = ['/EHsc', '/WX', '/wd4355', '/wd4800'] + CCFLAGS = ['/EHsc', '/wd4355', '/wd4800'] ) + if windows_env.Bit('werror'): + windows_env.Append(CCFLAGS = '/WX') # This linker option allows us to ensure our builds are compatible with # Chromium, which uses it. From 53000ae33e95a322568210cd779221c81a4efa6c Mon Sep 17 00:00:00 2001 From: slipher Date: Thu, 2 Jul 2026 23:57:22 -0500 Subject: [PATCH 05/11] Tests: fix Windows exit codes for Python 3 The 32-bit Windows exit codes are interpreted as signed in Python 2 and unsigned in Python 3. --- tests/gdb/gdb_test.py | 2 +- tests/trusted_crash/crash_in_syscall/test_host.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/gdb/gdb_test.py b/tests/gdb/gdb_test.py index c5ba45561b..e2f98a9da6 100644 --- a/tests/gdb/gdb_test.py +++ b/tests/gdb/gdb_test.py @@ -14,7 +14,7 @@ if sys.platform == 'win32': - RETURNCODE_KILL = -9 + RETURNCODE_KILL = -9 & 0xffffffff else: RETURNCODE_KILL = -9 & 0xff diff --git a/tests/trusted_crash/crash_in_syscall/test_host.c b/tests/trusted_crash/crash_in_syscall/test_host.c index a9704c3da1..1dfa183b2a 100644 --- a/tests/trusted_crash/crash_in_syscall/test_host.c +++ b/tests/trusted_crash/crash_in_syscall/test_host.c @@ -195,7 +195,7 @@ static LONG WINAPI ExceptionHandler(EXCEPTION_POINTERS *exc_info) { * although the unsigned values are used in headers and are more * widely recognised */ - fprintf(stderr, "** intended_exit_status=%i\n", STATUS_ACCESS_VIOLATION); + fprintf(stderr, "** intended_exit_status=%u\n", STATUS_ACCESS_VIOLATION); } else if (strcmp(g_crash_type, "NACL_TEST_CRASH_LOG_FATAL") == 0 || strcmp(g_crash_type, "NACL_TEST_CRASH_CHECK_FAILURE") == 0) { fprintf(stderr, "** intended_exit_status=trusted_sigabrt\n"); From 03d01df585edc85d3e21f18f9bcd2b977949faee Mon Sep 17 00:00:00 2001 From: slipher Date: Fri, 3 Jul 2026 02:50:27 -0500 Subject: [PATCH 06/11] Windows: set a configurable MinGW path The Windows builds are mostly based on MSVC, but they use the MinGW assembler. Also use this to provide readelf for the run.py test. --- SConstruct | 16 ++++++---------- tests/run_py/nacl.scons | 5 +++++ 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/SConstruct b/SConstruct index 44eaddb7d9..53ae118fec 100755 --- a/SConstruct +++ b/SConstruct @@ -199,6 +199,8 @@ ACCEPTABLE_ARGUMENTS = set([ 'pnacl_newlib_dir', # Allows override of the pnacl newlib toolchain directory. 'saigo_newlib_dir', + # MinGW install directory, for Windows builds. Required. + 'mingw_dir', # Allows overriding the version number in the toolchain's # FEATURE_VERSION file. This is used for PNaCl ABI compatibility # testing. @@ -2348,16 +2350,10 @@ def MakeWindowsEnv(platform=None): # We use the GNU assembler (gas) on Windows so that we can use the # same .S assembly files on all platforms. Microsoft's assembler uses # a completely different syntax for x86 code. - if windows_env.Bit('build_x86_64'): - # This assembler only works for x86-64 code. - windows_env['WINASM'] = \ - windows_env.File('$SOURCE_ROOT/third_party/mingw-w64/mingw/bin/' - 'x86_64-w64-mingw32-as.exe').abspath - else: - # This assembler only works for x86-32 code. - windows_env['WINASM'] = \ - windows_env.File('$SOURCE_ROOT/third_party/gnu_binutils/files/' - 'as').abspath + mingw_dir = os.path.abspath(ARGUMENTS['mingw_dir']) + windows_env['MINGW_BIN'] = os.path.join(mingw_dir, 'bin') + windows_env['WINASM'] = os.path.join(windows_env['MINGW_BIN'], 'as.exe') + return windows_env (windows_debug_env, diff --git a/tests/run_py/nacl.scons b/tests/run_py/nacl.scons index 1aa7c2e46f..4b3f07d017 100644 --- a/tests/run_py/nacl.scons +++ b/tests/run_py/nacl.scons @@ -21,6 +21,11 @@ elif env.Bit('nacl_glibc'): # With the new glibc port, it won't work at all. Return() +if env['TRUSTED_ENV'].Bit('windows'): + # To find readelf. Saigo also has a readelf but it's named x86_64-nacl-readelf (etc.) + env = env.Clone() + env.PrependENVPath('PATH', env['TRUSTED_ENV']['MINGW_BIN']) + sel_ldr = env.GetSelLdr() if sel_ldr is None: print('WARNING: no sel_ldr found. Skipping test %s' % name) From 01b6ee297e9b43f0a6224ec8e078da6f23e56792 Mon Sep 17 00:00:00 2001 From: slipher Date: Fri, 3 Jul 2026 02:14:33 -0500 Subject: [PATCH 07/11] run.py: use .exe extension when searching readelf In run.py, on Windows add the extension to search for readelf.exe rather than readelf. It worked by accident upstream since there was a bash script named readelf in the same directory as readelf.exe. --- run.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/run.py b/run.py index 5266060108..653dd50e79 100755 --- a/run.py +++ b/run.py @@ -594,6 +594,8 @@ def FindReadElf(): candidates.append(os.path.join(path, 'readelf')) for readelf in candidates: + if pynacl.platform.IsWindows(): + readelf += '.exe' if os.path.exists(readelf): return readelf From 0ff78bddffa10b6d23dcd165b815e07d1404a69d Mon Sep 17 00:00:00 2001 From: slipher Date: Mon, 29 Jun 2026 18:39:25 -0500 Subject: [PATCH 08/11] Revert "Disable DEP qualifications on Windows as they are always true." This reverts commit 5361d3c68b67a413c51150bf8844bf19d534db5b. Makes platform_qual_test fail. I think it would be better to remove the check in production but keep it in the test. --- .../platform_qualify/win/nacl_dep_qualify.c | 30 ++++++++++++++----- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/trusted/platform_qualify/win/nacl_dep_qualify.c b/src/trusted/platform_qualify/win/nacl_dep_qualify.c index f28cfe54e1..e687fdafeb 100644 --- a/src/trusted/platform_qualify/win/nacl_dep_qualify.c +++ b/src/trusted/platform_qualify/win/nacl_dep_qualify.c @@ -11,21 +11,35 @@ #include "native_client/src/include/portability.h" +#include +#include +#include + #include "native_client/src/trusted/platform_qualify/nacl_dep_qualify.h" + int NaClAttemptToExecuteDataAtAddr(uint8_t *thunk_buffer, size_t size) { - /* - * All supported versions of Windows have DEP. No need to test this. - */ - return 1; + int got_fault = 0; + nacl_void_thunk thunk = NaClGenerateThunk(thunk_buffer, size); + __try { + thunk(); + } __except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION + ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { + got_fault = 1; + } + return got_fault; } /* * Returns 1 if Data Execution Prevention is present and working. */ int NaClAttemptToExecuteData(void) { - /* - * All supported versions of Windows have DEP. No need to test this. - */ - return 1; + int result; + uint8_t *thunk_buffer = malloc(64); + if (NULL == thunk_buffer) { + return 0; + } + result = NaClAttemptToExecuteDataAtAddr(thunk_buffer, 64); + free(thunk_buffer); + return result; } From 257ff06794e037ef404d52388518205daa19ee24 Mon Sep 17 00:00:00 2001 From: slipher Date: Wed, 1 Jul 2026 15:08:19 -0500 Subject: [PATCH 09/11] Enforce LF line endings for a piece of test data The test target run_redir_test breaks if files are checked out with CRLF line endings. Note: Chromium suggests that you should set core.autocrlf = false in Git for working with any of their repositories. --- tests/redir/.gitattributes | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 tests/redir/.gitattributes diff --git a/tests/redir/.gitattributes b/tests/redir/.gitattributes new file mode 100644 index 0000000000..5f761b1bda --- /dev/null +++ b/tests/redir/.gitattributes @@ -0,0 +1,2 @@ +redir_test.stderr eol=lf +redir_test.stdout eol=lf From 46c0298adbb188b5c36ac32eb0ef11a940cc804d Mon Sep 17 00:00:00 2001 From: slipher Date: Wed, 1 Jul 2026 17:51:53 -0500 Subject: [PATCH 10/11] Enable tests for Saigo only broken with other NaCl toolchains --- tests/toolchain/nacl.scons | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/toolchain/nacl.scons b/tests/toolchain/nacl.scons index 963a253d29..a098fbd170 100644 --- a/tests/toolchain/nacl.scons +++ b/tests/toolchain/nacl.scons @@ -104,7 +104,7 @@ if env.Bit('bitcode') or env.Bit('nacl_clang'): EXTRA_CCFLAGS='-DSHOULD_INLINE=' + str(should_inline), # inline case is currently broken: # https://code.google.com/p/nativeclient/issues/detail?id=4170 - is_broken=should_inline) + is_broken=should_inline and not env.Bit('saigo')) AddIntrinsicTest(env, 'llvm_math_intrinsics.cc', '0', golden_file=env.File('llvm_math_intrinsics.stdout')) # Also test the math functions with -ffast-math, so we are a tiny bit more @@ -459,7 +459,7 @@ c99_env = env.Clone() c99_env.Append(CFLAGS=['-std=c99']) # VLA test is broken on nacl-gcc x86-64 (segfaults in test_two_recursion()). # http://code.google.com/p/nativeclient/issues/detail?id=3527 -vla_is_broken = not env.Bit('bitcode') and env.Bit('build_x86_64') +vla_is_broken = not env.Bit('bitcode') and env.Bit('build_x86_64') and not env.Bit('saigo') nexe = c99_env.ComponentProgram('vla', 'vla.c', EXTRA_LIBS=['${NONIRT_LIBS}']) node = env.CommandSelLdrTestNacl('vla.out', nexe, From fcf07df786f73aae4551d6d937a79d48afde19ae Mon Sep 17 00:00:00 2001 From: slipher Date: Fri, 3 Jul 2026 03:22:40 -0500 Subject: [PATCH 11/11] Delete scons.bat If you had scons.exe installed in the PATH (as opposed to doing python -m SCons), it would be annoying that typing `scons` finds scons.bat before scons.exe. --- scons.bat | 28 ---------------------------- 1 file changed, 28 deletions(-) delete mode 100755 scons.bat diff --git a/scons.bat b/scons.bat deleted file mode 100755 index d6b63d8efa..0000000000 --- a/scons.bat +++ /dev/null @@ -1,28 +0,0 @@ -@echo off -:: Copyright (c) 2011 The Native Client Authors. All rights reserved. -:: Use of this source code is governed by a BSD-style license that can be -:: found in the LICENSE file. - -setlocal - -:: If this batch file is run directly thru cygwin, we will get the wrong -:: version of python. To avoid this, if we detect cygwin, we need to then -:: invoke the shell script which will then re-invoke this batch file with -:: cygwin stripped out of the path. -:: Detect cygwin by trying to run bash. -bash --version >NUL 2>&1 -if %ERRORLEVEL% == 0 ( - bash "%~dp0\scons" %* || exit 1 - goto end -) - -:: Preserve a copy of the PATH (in case we need it later, mainly for cygwin). -set PRESCONS_PATH=%PATH% - -:: Stop incessant CYGWIN complains about "MS-DOS style path" -set CYGWIN=nodosfilewarning %CYGWIN% - -:: Run the included copy of scons. -python3 "%~dp0\scons.py" %* - -:end