diff --git a/.github/workflows/build_test.yml b/.github/workflows/build_test.yml index 22f94477a..cbd54c9f9 100644 --- a/.github/workflows/build_test.yml +++ b/.github/workflows/build_test.yml @@ -84,6 +84,15 @@ jobs: python_packages: pywin32 mingw_url: https://github.com/niXman/mingw-builds-binaries/releases/download/16.1.0-rt_v14-rev1/x86_64-16.1.0-release-posix-seh-msvcrt-rt_v14-rev1.7z + - name: Windows i686 MinGW + vm_image: windows-2022 + sdk_platform: windows-amd64 + scons_build_args: platform=x86-32 --no-clang mingw=1 werror=1 mingw_dir=mingw/mingw tls_edit_i686=1 + scons_tests: small_tests medium_tests large_tests disable_tests=run_toolchain_python_tests + vpython: pyenv/Scripts/python + python_packages: pywin32 + mingw_url: https://github.com/niXman/mingw-builds-binaries/releases/download/16.1.0-rt_v14-rev1/i686-16.1.0-release-posix-dwarf-msvcrt-rt_v14-rev1.7z + # Azure exposed matrix values as environment variables; do the same here # so the scripts below can stay as plain shell. env: @@ -151,4 +160,4 @@ jobs: run: | set -xue parallelism="$(${NPROC_COMMAND:-nproc})" - ${VPYTHON} -m SCons --mode=opt-host,nacl saigo=1 saigo_newlib_dir=sdk/sdk ${SCONS_BUILD_ARGS} ${SCONS_TESTS} -j${parallelism} --verbose --keep-going disable_flaky_tests=1 + ${VPYTHON} -m SCons -Q --mode=opt-host,nacl saigo=1 saigo_newlib_dir=sdk/sdk ${SCONS_BUILD_ARGS} ${SCONS_TESTS} -j${parallelism} --verbose --keep-going disable_flaky_tests=1 diff --git a/README.md b/README.md index e24f101e8..11b847c46 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,8 @@ Target & compiler|Build status|Target & compiler|Build status Linux amd64 GCC|[![Build Status](https://img.shields.io/github/check-runs/DaemonEngine/native_client/master?nameFilter=Linux%20amd64%20GCC)](https://github.com/DaemonEngine/native_client/actions/workflows/build_test.yml?query=branch%3Amaster)|Windows amd64 MSVC|[![Build Status](https://img.shields.io/github/check-runs/DaemonEngine/native_client/master?nameFilter=Windows%20amd64%20MSVC)](https://github.com/DaemonEngine/native_client/actions/workflows/build_test.yml?query=branch%3Amaster) Linux amd64 Clang|[![Build Status](https://img.shields.io/github/check-runs/DaemonEngine/native_client/master?nameFilter=Linux%20amd64%20Clang)](https://github.com/DaemonEngine/native_client/actions/workflows/build_test.yml?query=branch%3Amaster)|Windows i686 MSVC|[![Build Status](https://img.shields.io/github/check-runs/DaemonEngine/native_client/master?nameFilter=Windows%20i686%20MSVC)](https://github.com/DaemonEngine/native_client/actions/workflows/build_test.yml?query=branch%3Amaster) Linux i686 GCC|[![Build Status](https://img.shields.io/github/check-runs/DaemonEngine/native_client/master?nameFilter=Linux%20i686%20GCC)](https://github.com/DaemonEngine/native_client/actions/workflows/build_test.yml?query=branch%3Amaster)|Windows amd64 MinGW|[![Build Status](https://img.shields.io/github/check-runs/DaemonEngine/native_client/master?nameFilter=Windows%20amd64%20MinGW)](https://github.com/DaemonEngine/native_client/actions/workflows/build_test.yml?query=branch%3Amaster) -Linux armhf GCC|[![Build Status](https://img.shields.io/github/check-runs/DaemonEngine/native_client/master?nameFilter=Linux%20armhf%20GCC)](https://github.com/DaemonEngine/native_client/actions/workflows/build_test.yml?query=branch%3Amaster)|macOS amd64 AppleClang|[![Build Status](https://img.shields.io/github/check-runs/DaemonEngine/native_client/master?nameFilter=macOS%20amd64%20AppleClang)](https://github.com/DaemonEngine/native_client/actions/workflows/build_test.yml?query=branch%3Amaster) +Linux armhf GCC|[![Build Status](https://img.shields.io/github/check-runs/DaemonEngine/native_client/master?nameFilter=Linux%20armhf%20GCC)](https://github.com/DaemonEngine/native_client/actions/workflows/build_test.yml?query=branch%3Amaster)|Windows i686 MinGW|[![Build Status](https://img.shields.io/github/check-runs/DaemonEngine/native_client/master?nameFilter=Windows%20i686%20MinGW)](https://github.com/DaemonEngine/native_client/actions/workflows/build_test.yml?query=branch%3Amaster) +macOS amd64 AppleClang|[![Build Status](https://img.shields.io/github/check-runs/DaemonEngine/native_client/master?nameFilter=macOS%20amd64%20AppleClang)](https://github.com/DaemonEngine/native_client/actions/workflows/build_test.yml?query=branch%3Amaster) Native Client (also known as NaCl) is a sandboxing technology by Google. It was used by Chrome extensions and Chrome apps. diff --git a/SConstruct b/SConstruct index 69aaa7939..8cebb70a3 100755 --- a/SConstruct +++ b/SConstruct @@ -277,6 +277,9 @@ def SetUpArgumentBits(env): BitFromArgument(env, 'mingw', default=False, desc='Use MinGW toolchain for trusted build') + BitFromArgument(env, 'tls_edit_i686', default=False, + desc='Build tls_edit as an i686 Windows host tool') + BitFromArgument(env, 'pnacl_native_clang_driver', default=False, desc='Use the (experimental) native PNaCl Clang driver') @@ -2314,6 +2317,9 @@ def MakeWindowsEnv(platform=None): if windows_env.Bit('mingw'): # Some C++-using binaries are linked with the C compiler windows_env.Append(LIBS = ['stdc++']) + if windows_env.Bit('build_x86_32'): + # Enable SSE2 for x86-32 MinGW builds so SSE intrinsics compile correctly. + windows_env.Append(CCFLAGS = ['-msse2']) else: # TODO(bsy) remove 4355 once cross-repo # NACL_ALLOW_THIS_IN_INITIALIZER_LIST changes go in. @@ -2328,7 +2334,8 @@ def MakeWindowsEnv(platform=None): # This linker option allows us to ensure our builds are compatible with # Chromium, which uses it. if windows_env.Bit('build_x86_32'): - windows_env.Append(LINKFLAGS = "/safeseh") + if not windows_env.Bit('mingw'): + windows_env.Append(LINKFLAGS = "/safeseh") mingw_dir = os.path.abspath(ARGUMENTS.get('mingw_dir', 'You.must.provide.the.mingw_dir.argument')) windows_env['MINGW_BIN'] = os.path.join(mingw_dir, 'bin') @@ -3718,6 +3725,15 @@ def LinkTrustedEnv(selected_envs): def MakeBuildEnv(): build_platform = GetBuildPlatform() + tls_edit_i686 = pre_base_env.Bit('tls_edit_i686') + if tls_edit_i686: + if not pre_base_env.Bit('mingw'): + raise UserError('tls_edit_i686 requires mingw=1') + if GetTargetPlatform() != 'x86-32': + raise UserError( + 'tls_edit_i686 requires a 32-bit target (platform=x86-32)') + build_platform = 'x86-32' + # Build Platform Base Function platform_func_map = { 'win32' : MakeWindowsEnv, @@ -3728,10 +3744,21 @@ def MakeBuildEnv(): } if sys.platform not in platform_func_map: raise UserError('Unrecognized host platform: %s', sys.platform) - make_env_func = platform_func_map[sys.platform] + # tls_edit_i686 builds a Windows host tool with the i686 MinGW + # toolchain, even when SCons itself is running on Linux. + if tls_edit_i686: + make_env_func = MakeWindowsEnv + else: + make_env_func = platform_func_map[sys.platform] build_env = make_env_func(build_platform) build_env['IS_BUILD_ENV'] = True + if tls_edit_i686: + build_env.Append(LINKFLAGS=[ + '-static', + '-static-libgcc', + '-static-libstdc++', + ]) # Building tls_edit depends on gio, platform, and validator_ragel. build_env['BUILD_SCONSCRIPTS'] = [ diff --git a/src/trusted/platform_qualify/arch/x86/vcpuid.c b/src/trusted/platform_qualify/arch/x86/vcpuid.c index dbefa9b11..27e5abb32 100644 --- a/src/trusted/platform_qualify/arch/x86/vcpuid.c +++ b/src/trusted/platform_qualify/arch/x86/vcpuid.c @@ -38,7 +38,15 @@ const int kMagicConst_ROUNDSS = 0xc0000000; const int kMagicConst_POPCNT = 13; const int kMagicConst_CRC32 = 0xb906c3ea; -#if !(NACL_WINDOWS && (NACL_BUILD_SUBARCH == 64)) +#if (NACL_WINDOWS && defined(_MSC_VER) && (NACL_BUILD_SUBARCH == 64)) +# define NACL_WINDOWS_MSC_64 +#endif + +#if (NACL_WINDOWS && !defined(_MSC_VER)) +# define NACL_WINDOWS_MINGW +#endif + +#if !defined(NACL_WINDOWS_MSC_64) && !defined(NACL_WINDOWS_MINGW) static int asm_HasMMX(void) { volatile int before, after; before = kMagicConst; @@ -386,8 +394,9 @@ static int asm_HasCX8(void) { #endif /* 0 */ #endif /* 64-bit Windows */ -#if NACL_WINDOWS && (NACL_BUILD_SUBARCH == 64) +#if defined(NACL_WINDOWS_MSC_64) || defined(NACL_WINDOWS_MINGW) static int CheckCPUFeatureDetection(NaClCPUFeaturesX86 *cpuf) { + (void)cpuf; /* Unfortunately the asm_ tests will not work on 64-bit Windows */ return 0; } diff --git a/src/trusted/service_runtime/arch/x86_32/nacl_switch_to_app_32.c b/src/trusted/service_runtime/arch/x86_32/nacl_switch_to_app_32.c index 47e4d9d9b..5a5ec20e6 100644 --- a/src/trusted/service_runtime/arch/x86_32/nacl_switch_to_app_32.c +++ b/src/trusted/service_runtime/arch/x86_32/nacl_switch_to_app_32.c @@ -71,7 +71,7 @@ NORETURN void NaClStartThreadInApp(struct NaClAppThread *natp, NaClSwitch(context); -#if NACL_WINDOWS && defined(__clang__) +#if NACL_WINDOWS && (defined(__clang__) || defined(__GNUC__)) /* * NaClSwitch is a function pointer in x86_32 and there's no way to mark * the function pointed to by a function pointer as noreturn in clang-cl mode. diff --git a/src/trusted/service_runtime/arch/x86_32/sel_rt_32.h b/src/trusted/service_runtime/arch/x86_32/sel_rt_32.h index cce501c92..6f260e8f5 100644 --- a/src/trusted/service_runtime/arch/x86_32/sel_rt_32.h +++ b/src/trusted/service_runtime/arch/x86_32/sel_rt_32.h @@ -98,9 +98,17 @@ struct NaClGsSegment { */ #if NACL_WINDOWS /* Align gs_segment for better performance on Intel Atom */ -__declspec(align(64)) +#if defined(_MSC_VER) +#define NACL_THREAD_CONTEXT_ALIGN __declspec(align(64)) +#elif defined(__GNUC__) +#define NACL_THREAD_CONTEXT_ALIGN __attribute__((aligned(64))) +#else +#define NACL_THREAD_CONTEXT_ALIGN #endif -struct NaClThreadContext { +#else +#define NACL_THREAD_CONTEXT_ALIGN +#endif +struct NACL_THREAD_CONTEXT_ALIGN NaClThreadContext { /* * We align gs_segment to a multiple of 64 bytes because otherwise * memory accesses through the %gs segment are slow on Intel Atom diff --git a/src/trusted/service_runtime/win/sel_segments.c b/src/trusted/service_runtime/win/sel_segments.c index f18785d9a..fd5dd4fdd 100644 --- a/src/trusted/service_runtime/win/sel_segments.c +++ b/src/trusted/service_runtime/win/sel_segments.c @@ -16,7 +16,11 @@ uint16_t NaClGetCs(void) { uint16_t seg1; +#if defined(__GNUC__) + __asm__ volatile ("mov %%cs, %0" : "=r"(seg1)); +#else __asm mov seg1, cs; +#endif return seg1; } @@ -25,59 +29,95 @@ uint16_t NaClGetCs(void) { uint16_t NaClGetDs(void) { uint16_t seg1; +#if defined(__GNUC__) + __asm__ volatile ("mov %%ds, %0" : "=r"(seg1)); +#else __asm mov seg1, ds; +#endif return seg1; } void NaClSetDs(uint16_t seg1) { +#if defined(__GNUC__) + __asm__ volatile ("mov %0, %%ds" : : "r"(seg1)); +#else __asm mov ds, seg1; +#endif } uint16_t NaClGetEs(void) { uint16_t seg1; +#if defined(__GNUC__) + __asm__ volatile ("mov %%es, %0" : "=r"(seg1)); +#else __asm mov seg1, es; +#endif return seg1; } void NaClSetEs(uint16_t seg1) { +#if defined(__GNUC__) + __asm__ volatile ("mov %0, %%es" : : "r"(seg1)); +#else __asm mov es, seg1; +#endif } uint16_t NaClGetFs(void) { uint16_t seg1; +#if defined(__GNUC__) + __asm__ volatile ("mov %%fs, %0" : "=r"(seg1)); +#else __asm mov seg1, fs; +#endif return seg1; } void NaClSetFs(uint16_t seg1) { +#if defined(__GNUC__) + __asm__ volatile ("mov %0, %%fs" : : "r"(seg1)); +#else __asm mov fs, seg1; +#endif } uint16_t NaClGetGs(void) { uint16_t seg1; +#if defined(__GNUC__) + __asm__ volatile ("mov %%gs, %0" : "=r"(seg1)); +#else __asm mov seg1, gs; +#endif return seg1; } void NaClSetGs(uint16_t seg1) { +#if defined(__GNUC__) + __asm__ volatile ("mov %0, %%gs" : : "r"(seg1)); +#else __asm mov gs, seg1; +#endif } uint16_t NaClGetSs(void) { uint16_t seg1; +#if defined(__GNUC__) + __asm__ volatile ("mov %%ss, %0" : "=r"(seg1)); +#else __asm mov seg1, ss; +#endif return seg1; } @@ -85,7 +125,11 @@ uint16_t NaClGetSs(void) { uint32_t NaClGetStackPtr(void) { uint32_t stack_ptr; +#if defined(__GNUC__) + __asm__ volatile ("mov %%esp, %0" : "=r"(stack_ptr)); +#else _asm mov stack_ptr, esp; +#endif return stack_ptr; } #endif diff --git a/tests/trusted_crash/crash_in_syscall/test_host.c b/tests/trusted_crash/crash_in_syscall/test_host.c index 1e8f0919c..4cf25deff 100644 --- a/tests/trusted_crash/crash_in_syscall/test_host.c +++ b/tests/trusted_crash/crash_in_syscall/test_host.c @@ -127,7 +127,7 @@ static void Backtrace(CONTEXT *initial_context) { } fprintf(stderr, "#%i: ip=%p stack=%llx frame=%llx ", frame_number, - (void *) frame.AddrPC.Offset, + (void *) (uintptr_t) frame.AddrPC.Offset, frame.AddrStack.Offset, frame.AddrFrame.Offset); PrintSymbolForAddress(frame.AddrPC.Offset);