Compare commits

..

6 Commits

Author SHA1 Message Date
Sam Attard
1681cc3a6c fix: derive v8_control_flow_integrity from target_os for win-arm64 cross-compile
The snapshot toolchain (linux:clang_x64_v8_arm64) has current_os=linux,
so arm_control_flow_integrity defaults to 'standard' there while the
win-arm64 target gets 'none'. v8_control_flow_integrity then disagrees
between mksnapshot and the runtime, mksnapshot bakes pacibsp/autibsp
into the builtins, and electron.exe fast-fails with
FAST_FAIL_POINTER_AUTH_INVALID_RETURN_ADDRESS on real hardware.

Key v8_control_flow_integrity on target_os so it evaluates the same in
every toolchain.
2026-04-08 05:07:21 +00:00
Sam Attard
890a9c2bc9 build: align release workflow with Linux cross-compile, drop in-repo main.star
- windows-publish.yml: move all three publish jobs to the Linux runner +
  ghcr.io/electron/build container (matching build.yml). The publish
  segment was regenerated from -build.yml and now assumes a Linux host;
  leaving releases on Windows runners would have broken them.
- build-electron/action.yml: drop the Profile Windows Toolchain step.
  profile_toolchain.py reads installed_software.json (a Windows-host WMI
  dump that no longer exists); upload.py's consumer of the resulting
  windows_toolchain_profile.json is gated on sys.platform == 'win32' so
  it's skipped on the Linux host anyway.
- pipeline-segment-electron-{build,publish}.yml: drop the
  rm -rf vs_files* — the checkout cache doesn't include the toolchain,
  so this was a no-op. Keep the e d vs_toolchain.py update --force which
  actually fetches it.
- Drop build/siso/main.star + ELECTRON_BUILD_TOOLS_MAIN_STAR and bump
  BUILD_TOOLS_SHA to 03f1603 (electron/build-tools#840), which has the
  win_sdk.enabled() gate so the in-repo override is no longer needed.
2026-04-08 04:29:09 +00:00
Sam Attard
8c9f067887 fix: use %zu for size_t in V8 arm64 EmitUnwindData SNPrintF
The arm64 EmitUnwindData path now compiles on Linux (-Wformat strict)
since the unwind patch re-gated it on V8_TARGET_OS_WIN_ARM64. The
existing %u for size_t/.size() was a latent mismatch that clang-cl on
Windows does not warn about.
2026-04-08 03:47:08 +00:00
Sam Attard
0e2faaed30 build: cross-compile Windows on Linux
Move the Windows build jobs to Linux runners using the same
ghcr.io/electron/build container as the gn-check job (with /dev/fuse
and SYS_ADMIN for ciopfs).

- build-electron action: set target_os=win/target_cpu/use_v8_context_snapshot
  GN args for all Windows arches; point ELECTRON_BUILD_TOOLS_MAIN_STAR at
  the in-repo build/siso/main.star; drop the powershell build/siso-report/
  installed_software/mksnapshot.zip steps in favour of the unified bash
  paths now that the host is Linux.
- pipeline-segment-electron-build: set ELECTRON_DEPOT_TOOLS_WIN_TOOLCHAIN,
  use AKS cache restore for Windows (Linux container), skip fix-sync for
  Windows (Linux-synced tree needs no fixup), and run the win_toolchain
  hook with target_os=['win'] so the MSVC toolchain lands.
- build/siso/main.star: in-repo copy of build-tools' main.star with the
  mswsock.h/Lm.h :headers extension keyed on win_sdk.enabled() (target
  OS) instead of runtime.os, so siso uploads those SDK headers to RBE on
  a Linux host.
- move-artifacts.sh: classify Linux+ELECTRON_DEPOT_TOOLS_WIN_TOOLCHAIN
  as a win build.

Derived from the build-win-on-linux branch with the wine path removed —
mksnapshot now runs natively on the Linux host with --target_os=win and
the V8 patches in the previous commits ensure it emits Win64 unwind
data and uses the right snapshot toolchain for arm64.
2026-04-08 03:28:05 +00:00
Sam Attard
88d98d03b2 fix: select arm64-simulator snapshot toolchain for win-arm64 on Linux hosts
V8's snapshot_toolchain.gni assumed a Windows host when targeting
win-arm64 and picked plain host_toolchain (linux:clang_x64), so
mksnapshot was built with V8_TARGET_ARCH_X64 and produced an x64
builtins blob. Restrict that path to host_os == win so Linux uses
//build/toolchain/linux:clang_x64_v8_arm64.
2026-04-08 03:28:04 +00:00
Sam Attard
07ad8ba6bf fix: emit Win64 .pdata/.xdata for V8 embedded builtins when cross-compiling
V8's embedded-builtins unwind-info path was gated on the host
V8_OS_WIN64, so a Linux-hosted mksnapshot targeting Windows compiled it
all out and embedded.S contained no .pdata/.xdata for the builtins blob.
This left cross-compiled electron.exe with no RUNTIME_FUNCTION records
for V8 builtins, breaking Crashpad/ETW stack walks through them.

Re-gate the generation half on V8_TARGET_OS_WIN64 (new), keep runtime
RtlAddFunctionTable registration on the host macro. Covers x64 and
arm64. Also key ia32 AllocateStackSpace's guard-page probing and arm64
Printf's varargs ABI on V8_TARGET_OS_WIN (matching x64/arm64 stack
probing which already do).
2026-04-08 03:28:04 +00:00
16 changed files with 987 additions and 419 deletions

View File

@@ -42,111 +42,8 @@ runs:
shell: bash
if: ${{ inputs.target-platform == 'win' }}
run: |
GN_APPENDED_ARGS="$GN_EXTRA_ARGS target_cpu=\"${{ inputs.target-arch }}\" use_v8_context_snapshot=true v8_win_cross_compile_using_wine=true target_os=\"win\""
GN_APPENDED_ARGS="$GN_EXTRA_ARGS target_os=\"win\" target_cpu=\"${{ inputs.target-arch }}\" use_v8_context_snapshot=true"
echo "GN_EXTRA_ARGS=$GN_APPENDED_ARGS" >> $GITHUB_ENV
echo "ELECTRON_BUILD_TOOLS_MAIN_STAR=`pwd`/src/electron/build/siso/main.star" >> $GITHUB_ENV
- name: Install wine for Windows builds on non-Windows hosts
shell: bash
if: ${{ inputs.target-platform == 'win' && runner.os != 'Windows' }}
run: |
sudo mkdir -pm755 /etc/apt/keyrings
wget -O - https://dl.winehq.org/wine-builds/winehq.key | sudo gpg --dearmor -o /etc/apt/keyrings/winehq-archive.key -
sudo dpkg --add-architecture i386
sudo wget -NP /etc/apt/sources.list.d/ https://dl.winehq.org/wine-builds/ubuntu/dists/jammy/winehq-jammy.sources
sudo apt-get update
sudo apt install -y --install-recommends winehq-stable libgcc-s1:i386 libgcc-s1
# Increase virtual memory limits for Wine's VirtualAlloc (V8 sandbox
# reserves a very large contiguous region that fails under default limits)
sudo sysctl vm.mmap_min_addr
sudo sysctl -w vm.mmap_min_addr=65536
sudo sysctl -w vm.max_map_count=1048576
sudo sysctl -w vm.overcommit_memory=1
sudo sysctl -w kernel.randomize_va_space=0
if [ -x /usr/bin/wine ]; then
WINE_PATH=/usr/bin/wine
elif command -v wine >/dev/null 2>&1; then
WINE_PATH=$(command -v wine)
fi
if [ -z "$WINE_PATH" ] || [ ! -x "$WINE_PATH" ]; then
echo "ERROR: wine binary not found anywhere after install"
exit 1
fi
echo "Found wine at: $WINE_PATH"
export WINEPREFIX="$HOME/.wine"
mkdir -p "$WINEPREFIX"
echo "WINEPREFIX=$WINEPREFIX" >> $GITHUB_ENV
# Start a persistent Xvfb server for wine (xvfb-run per-invocation hangs
# because wineserver keeps the X connection alive)
export DISPLAY=:99.0
echo "DISPLAY=:99.0" >> $GITHUB_ENV
export XDG_RUNTIME_DIR=/tmp/runtime-$(whoami)
echo "XDG_RUNTIME_DIR=$XDG_RUNTIME_DIR" >> $GITHUB_ENV
mkdir -p "$XDG_RUNTIME_DIR"
echo "Starting Xvfb on :99 with 1024x768x24 resolution"
Xvfb :99 -screen 0 1024x768x24 &
echo "Wait for Xvfb to be ready"
# Wait for Xvfb to be ready (up to 5 seconds)
for i in $(seq 1 10); do
if xdpyinfo -display :99 >/dev/null 2>&1; then
echo "Xvfb is running on :99"
break
fi
echo "xvfb not ready yet, waiting..."
sleep 0.5
done
if ! xdpyinfo -display :99 >/dev/null 2>&1; then
echo "ERROR: Xvfb failed to start"
exit 1
fi
echo "Xvfb is ready; about to run wineboot"
export WINEDEBUG=-all
echo "WINEDEBUG=$WINEDEBUG" >> $GITHUB_ENV
export WINEARCH=win64
echo "WINEARCH=$WINEARCH" >> $GITHUB_ENV
WINEDLLOVERRIDES="mscoree,mshtml=" wineboot --init
echo "Done running wineboot"
# Initialize wine prefix to avoid first-run delays during build
#"$WINE_PATH" wineboot --init 2>/dev/null || true
WINE_WRAPPER="/usr/local/bin/xvfb-wine"
printf '#!/bin/sh\nsetarch x86_64 -R %s "$@"\n' "$WINE_PATH" | sudo tee "$WINE_WRAPPER" > /dev/null
sudo chmod +x "$WINE_WRAPPER"
GN_APPENDED_ARGS="$GN_EXTRA_ARGS v8_wine_path=\"$WINE_WRAPPER\""
# Pass wine path to GN so siso can find it regardless of PATH
GN_APPENDED_ARGS="$GN_EXTRA_ARGS v8_wine_path=\"$WINE_PATH\""
echo "GN_EXTRA_ARGS=$GN_APPENDED_ARGS" >> $GITHUB_ENV
echo "GN APPENDED_ARGS set with wine path: $GN_APPENDED_ARGS"
echo "Wine setup complete"
# - name: Download mksnapshot.zip
# shell: bash
# if: ${{ inputs.target-platform == 'win' }}
# run: |
# # Download mksnapshot.zip from https://electronbuildtools.blob.core.windows.net/windows-toolchains/mksnapshot.zip
# curl -L -o mksnapshot.zip https://electronbuildtools.blob.core.windows.net/windows-toolchains/mksnapshot.zip
# if [ $? -ne 0 ]; then
# echo "Failed to download mksnapshot.zip"
# exit 1
# fi
# if [ -f mksnapshot.zip ]; then
# echo "Successfully downloaded mksnapshot.zip"
# else
# echo "mksnapshot.zip not found after download"
# exit 1
# fi
# if [ -f mksnapshot.zip ]; then
# unzip mksnapshot.zip -d mksnapshot || true
# PREBUILT_MKSNAPSHOT="$(pwd)/mksnapshot/mksnapshot.exe"
# if [ -f "$PREBUILT_MKSNAPSHOT" ]; then
# GN_APPENDED_ARGS="$GN_EXTRA_ARGS v8_prebuilt_mksnapshot=\"$PREBUILT_MKSNAPSHOT\""
# echo "GN_EXTRA_ARGS=$GN_APPENDED_ARGS" >> $GITHUB_ENV
# echo "Using pre-built mksnapshot at $PREBUILT_MKSNAPSHOT"
# else
# echo "mksnapshot binary not found in mksnapshot.zip, will build from source"
# fi
# else
# echo "mksnapshot.zip not found, skipping unzip and PATH update"
# fi
- name: Add Clang problem matcher
shell: bash
run: echo "::add-matcher::src/electron/.github/problem-matchers/clang.json"
@@ -185,11 +82,7 @@ runs:
node electron/script/check-symlinks.js
# Build stats and object checksums
if [ "$TARGET_PLATFORM" = "win" ]; then
BUILD_STATS_ARGS="out/Default/siso.exe.INFO --out-dir out/Default --output-object-checksums object-checksums.${{ inputs.artifact-platform }}_${{ inputs.target-arch }}.json"
else
BUILD_STATS_ARGS="out/Default/siso.INFO --out-dir out/Default --output-object-checksums object-checksums.${{ inputs.artifact-platform }}_${{ inputs.target-arch }}.json"
fi
BUILD_STATS_ARGS="out/Default/siso.INFO --out-dir out/Default --output-object-checksums object-checksums.${{ inputs.artifact-platform }}_${{ inputs.target-arch }}.json"
if [ -f previous-object-checksums.json ]; then
BUILD_STATS_ARGS="$BUILD_STATS_ARGS --input-object-checksums previous-object-checksums.json"
fi
@@ -226,7 +119,7 @@ runs:
sed $SEDOPTION '/--warn-about-builtin-profile-data/d' out/Default/mksnapshot_args
sed $SEDOPTION '/--abort-on-bad-builtin-profile-data/d' out/Default/mksnapshot_args
(cd out/Default; zip mksnapshot.zip mksnapshot_args gen/v8/embedded.S)
(cd out/Default; zip mksnapshot.zip mksnapshot_args gen/v8/embedded.S)
- name: Generate Cross-Arch Snapshot (arm/arm64) ${{ inputs.step-suffix }}
shell: bash
if: ${{ (inputs.target-arch == 'arm' || inputs.target-arch == 'arm64') && inputs.target-platform == 'linux' }}
@@ -260,12 +153,6 @@ runs:
fi
electron/script/zip_manifests/check-zip-manifest.py out/Default/chromedriver.zip electron/script/zip_manifests/chromedriver_zip.$target_os.${{ inputs.target-arch }}.manifest
fi
- name: Profile Windows Toolchain ${{ inputs.step-suffix }}
shell: bash
if: ${{ inputs.is-release == 'true' && inputs.target-platform == 'win' }}
run: |
cd src
python3 electron/build/profile_toolchain.py --output-json=out/Default/windows_toolchain_profile.json
- name: Add msdia140.dll to Path ${{ inputs.step-suffix }}
shell: bash
if: ${{ inputs.is-release == 'true' && inputs.target-platform == 'win' }}

View File

@@ -15,7 +15,7 @@ runs:
git config --global core.preloadindex true
git config --global core.longpaths true
fi
export BUILD_TOOLS_SHA=1aa9dce0b3fa9353c38a6c3d4aac0249f0f68973
export BUILD_TOOLS_SHA=03f1603d5698368077ae830599b0b6f6248325b1
npm i -g @electron/build-tools
# Update depot_tools to ensure python
e d update_depot_tools

View File

@@ -11,12 +11,12 @@ on:
skip-macos:
type: boolean
description: 'Skip macOS builds'
default: true
default: false
required: false
skip-linux:
type: boolean
description: 'Skip Linux builds'
default: true
default: false
required: false
skip-windows:
type: boolean
@@ -108,7 +108,7 @@ jobs:
# Checkout Jobs
checkout-macos:
needs: setup
if: ${{ needs.setup.outputs.src == 'true' && inputs.skip-macos == 'false'}}
if: ${{ needs.setup.outputs.src == 'true' && !inputs.skip-macos}}
runs-on: electron-arc-centralus-linux-amd64-32core
permissions:
contents: read
@@ -138,7 +138,7 @@ jobs:
checkout-linux:
needs: setup
if: ${{ inputs.skip-linux == 'false' }}
if: ${{ !inputs.skip-linux}}
runs-on: electron-arc-centralus-linux-amd64-32core
permissions:
contents: read

View File

@@ -137,7 +137,7 @@ jobs:
- name: Enable windows toolchain
if: ${{ inputs.target-platform == 'win' }}
run: |
echo "ELECTRON_DEPOT_TOOLS_WIN_TOOLCHAIN=1" >> $GITHUB_ENV
echo "ELECTRON_DEPOT_TOOLS_WIN_TOOLCHAIN=1" >> $GITHUB_ENV
- name: Set GN_EXTRA_ARGS for Linux
if: ${{ inputs.target-platform == 'linux' }}
run: |
@@ -172,7 +172,7 @@ jobs:
if: ${{ inputs.target-platform != 'macos' }}
uses: ./src/electron/.github/actions/restore-cache-aks
with:
target-platform: ${{ inputs.target-platform }}
target-platform: ${{ inputs.target-platform }}
- name: Checkout Electron
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
@@ -189,14 +189,10 @@ jobs:
- name: Init Build Tools
run: |
e init -f --root=$(pwd) --out=Default ${{ inputs.gn-build-type }} --import ${{ inputs.gn-build-type }} --target-cpu ${{ inputs.target-arch }} --remote-build siso
e sanitize-config
- name: Run Electron Only Hooks
run: |
if [ "${{ inputs.target-platform }}" = "win" ]; then
rm -rf src/third_party/depot_tools/win_toolchain/vs_files*
fi
echo "solutions=[{'name':'src/electron','url':None,'deps_file':'DEPS','custom_vars':{'process_deps':False},'managed':False}]" > tmpgclient
if [ "${{ inputs.target-platform }}" = "win" ]; then
if [ "${{ inputs.target-platform }}" = "win" ]; then
echo "target_os=['win']" >> tmpgclient
fi
gclient runhooks --gclientfile=tmpgclient
@@ -242,11 +238,3 @@ jobs:
generate-symbols: '${{ inputs.generate-symbols }}'
upload-to-storage: '${{ inputs.upload-to-storage }}'
step-suffix: '(mas)'
- name: Wait for active SSH sessions
shell: bash
if: always() && !cancelled()
run: |
while [ -f /var/.ssh-lock ]
do
sleep 60
done

View File

@@ -142,6 +142,10 @@ jobs:
- name: Install AZCopy
if: ${{ inputs.target-platform == 'macos' }}
run: brew install azcopy
- name: Enable windows toolchain
if: ${{ inputs.target-platform == 'win' }}
run: |
echo "ELECTRON_DEPOT_TOOLS_WIN_TOOLCHAIN=1" >> $GITHUB_ENV
- name: Set GN_EXTRA_ARGS for Linux
if: ${{ inputs.target-platform == 'linux' }}
run: >
@@ -169,13 +173,15 @@ jobs:
echo "DEPSHASH=$DEPSHASH" >> $GITHUB_ENV
echo "CACHE_PATH=$DEPSHASH.tar" >> $GITHUB_ENV
- name: Restore src cache via AZCopy
if: ${{ inputs.target-platform != 'linux' }}
if: ${{ inputs.target-platform == 'macos' }}
uses: ./src/electron/.github/actions/restore-cache-azcopy
with:
target-platform: ${{ inputs.target-platform }}
- name: Restore src cache via AKS
if: ${{ inputs.target-platform == 'linux' }}
if: ${{ inputs.target-platform != 'macos' }}
uses: ./src/electron/.github/actions/restore-cache-aks
with:
target-platform: ${{ inputs.target-platform }}
- name: Checkout Electron
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
@@ -183,7 +189,7 @@ jobs:
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}
- name: Fix Sync
if: ${{ inputs.target-platform != 'linux' }}
if: ${{ inputs.target-platform == 'macos' }}
uses: ./src/electron/.github/actions/fix-sync
with:
target-platform: ${{ inputs.target-platform }}
@@ -196,7 +202,15 @@ jobs:
inputs.target-arch }} --remote-build siso
- name: Run Electron Only Hooks
run: |
e d gclient runhooks --spec="solutions=[{'name':'src/electron','url':None,'deps_file':'DEPS','custom_vars':{'process_deps':False},'managed':False}]"
echo "solutions=[{'name':'src/electron','url':None,'deps_file':'DEPS','custom_vars':{'process_deps':False},'managed':False}]" > tmpgclient
if [ "${{ inputs.target-platform }}" = "win" ]; then
echo "target_os=['win']" >> tmpgclient
fi
gclient runhooks --gclientfile=tmpgclient
# Fix VS Toolchain
if [ "${{ inputs.target-platform }}" = "win" ]; then
e d python3 src/build/vs_toolchain.py update --force
fi
- name: Regenerate DEPS Hash
run: >
(cd src/electron && git checkout .) && node

View File

@@ -61,7 +61,8 @@ jobs:
needs: checkout-windows
with:
environment: production-release
build-runs-on: electron-arc-centralus-windows-amd64-16core
build-runs-on: electron-arc-centralus-linux-amd64-32core
build-container: '{"image":"ghcr.io/electron/build:${{ needs.checkout-windows.outputs.build-image-sha }}","options":"--user root --device /dev/fuse --cap-add SYS_ADMIN","volumes":["/mnt/win-cache:/mnt/win-cache"]}'
target-platform: win
target-arch: x64
is-release: true
@@ -80,7 +81,8 @@ jobs:
needs: checkout-windows
with:
environment: production-release
build-runs-on: electron-arc-centralus-windows-amd64-16core
build-runs-on: electron-arc-centralus-linux-amd64-32core
build-container: '{"image":"ghcr.io/electron/build:${{ needs.checkout-windows.outputs.build-image-sha }}","options":"--user root --device /dev/fuse --cap-add SYS_ADMIN","volumes":["/mnt/win-cache:/mnt/win-cache"]}'
target-platform: win
target-arch: arm64
is-release: true
@@ -99,7 +101,8 @@ jobs:
needs: checkout-windows
with:
environment: production-release
build-runs-on: electron-arc-centralus-windows-amd64-16core
build-runs-on: electron-arc-centralus-linux-amd64-32core
build-container: '{"image":"ghcr.io/electron/build:${{ needs.checkout-windows.outputs.build-image-sha }}","options":"--user root --device /dev/fuse --cap-add SYS_ADMIN","volumes":["/mnt/win-cache:/mnt/win-cache"]}'
target-platform: win
target-arch: x86
is-release: true

View File

@@ -1,103 +0,0 @@
load("@builtin//encoding.star", "json")
load("@builtin//lib/gn.star", "gn")
load("@builtin//path.star", "path")
load("@builtin//runtime.star", "runtime")
load("@builtin//struct.star", "module")
load("@config//main.star", upstream_init = "init")
load("@config//win_sdk.star", "win_sdk")
load("@config//gn_logs.star", "gn_logs")
def init(ctx):
mod = upstream_init(ctx)
step_config = json.decode(mod.step_config)
# Buildbarn doesn't support input_root_absolute_path so disable that
for rule in step_config["rules"]:
input_root_absolute_path = rule.get("input_root_absolute_path", False)
if input_root_absolute_path:
rule.pop("input_root_absolute_path", None)
# Only wrap clang rules with a remote wrapper if not on Linux. These are currently only
# needed for X-Compile builds, which run on Windows and Mac.
if runtime.os != "linux":
for rule in step_config["rules"]:
if rule["name"].startswith("clang/") or rule["name"].startswith("clang-cl/"):
rule["remote_wrapper"] = "../../buildtools/reclient_cfgs/chromium-browser-clang/clang_remote_wrapper"
if "inputs" not in rule:
rule["inputs"] = []
rule["inputs"].append("buildtools/reclient_cfgs/chromium-browser-clang/clang_remote_wrapper")
rule["inputs"].append("third_party/llvm-build/Release+Asserts_linux/bin/clang")
if "executables" not in step_config:
step_config["executables"] = []
step_config["executables"].append("buildtools/reclient_cfgs/chromium-browser-clang/clang_remote_wrapper")
step_config["executables"].append("third_party/llvm-build/Release+Asserts_linux/bin/clang")
if runtime.os == "darwin":
# Update platforms to match our default siso config instead of reclient configs.
step_config["platforms"].update({
"clang": step_config["platforms"]["default"],
"clang_large": step_config["platforms"]["default"],
})
# Add additional Windows SDK headers needed by Electron
win_toolchain_dir = win_sdk.toolchain_dir(ctx)
if win_toolchain_dir:
sdk_version = gn_logs.read(ctx).get("windows_sdk_version")
step_config["input_deps"][win_toolchain_dir + ":headers"].extend([
# third_party/electron_node/deps/uv/include/uv/win.h includes mswsock.h
path.join(win_toolchain_dir, "Windows Kits", "10/Include", sdk_version, "um/mswsock.h"),
# third_party/electron_node/src/debug_utils.cc includes lm.h
path.join(win_toolchain_dir, "Windows Kits", "10/Include", sdk_version, "um/Lm.h"),
])
if runtime.os == "windows":
# Update platforms to match our default siso config instead of reclient configs.
step_config["platforms"].update({
"clang-cl": step_config["platforms"]["default"],
"clang-cl_large": step_config["platforms"]["default"],
"lld-link": step_config["platforms"]["default"],
})
# When cross-compiling for Windows using wine, mksnapshot.exe is run via
# wine64 on the local machine. The remote execution service cannot handle
# this, so force mksnapshot to run locally. The wine64 prefix also changes
# the command so the upstream v8/mksnapshot rule's command_prefix won't
# match — add an explicit rule for the wine-prefixed command.
if "args.gn" in ctx.metadata:
gn_args = gn.args(ctx)
if gn_args.get("v8_win_cross_compile_using_wine", "").strip('"') == "true":
# Force the existing v8/mksnapshot rule to run locally
for rule in step_config["rules"]:
if rule.get("name") == "v8/mksnapshot":
rule["remote"] = False
# Add a rule that matches the wine64-prefixed mksnapshot command.
# With wine, GN emits: python3 ../../v8/tools/run.py <wine_path> ./mksnapshot.exe
# The upstream command_prefix ("python3 ...run.py ./mksnapshot") won't
# match because wine_path appears before ./mksnapshot.exe.
wine_path = gn_args.get("v8_wine_path", "").strip('"')
if wine_path:
step_config["rules"].insert(0, {
"name": "v8/mksnapshot_wine",
"command_prefix": "python3 ../../v8/tools/run.py " + wine_path,
"remote": False,
"timeout": "2m",
"output_local": True,
})
# Same treatment for v8_context_snapshot_generator which uses
# gn_run_binary.py instead of v8/tools/run.py.
step_config["rules"].insert(0, {
"name": "v8/context_snapshot_wine",
"command_prefix": "python3 ../../build/gn_run_binary.py " + wine_path,
"remote": False,
"timeout": "2m",
"output_local": True,
})
return module(
"config",
step_config = json.encode(step_config),
filegroups = mod.filegroups,
handlers = mod.handlers,
)

View File

@@ -150,4 +150,3 @@ fix_use_fresh_lazynow_for_onendworkitemimpl_after_didruntask.patch
fix_pulseaudio_stream_and_icon_names.patch
fix_fire_menu_popup_start_for_dynamically_created_aria_menus.patch
feat_allow_enabling_extensions_on_custom_protocols.patch
chore_run_v8_context_snapshot_generator_through_wine_when.patch

View File

@@ -1,49 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: John Kleinschmidt <kleinschmidtorama@gmail.com>
Date: Tue, 7 Apr 2026 14:05:09 -0400
Subject: chore: run v8_context_snapshot_generator through Wine when
cross-compiling
When cross-compiling for Windows on Linux with Wine, the
v8_context_snapshot_generator binary is a Windows PE executable (.exe)
that cannot be run directly. Prepend the wine path to args and append
.exe to the binary name, matching the approach used for mksnapshot.
diff --git a/tools/v8_context_snapshot/BUILD.gn b/tools/v8_context_snapshot/BUILD.gn
index ec2357139826613e8b295cb01be341acb03b4737..6c4171dbaf7a76cfc89d71871b73058747675811 100644
--- a/tools/v8_context_snapshot/BUILD.gn
+++ b/tools/v8_context_snapshot/BUILD.gn
@@ -50,12 +50,27 @@ if (use_v8_context_snapshot) {
output_file = "$root_build_dir/$v8_context_snapshot_filename"
output_path = rebase_path(output_file, root_build_dir)
- args = [
- "./" + rebase_path(
- get_label_info(
- ":v8_context_snapshot_generator($v8_snapshot_toolchain)",
- "root_out_dir") + "/v8_context_snapshot_generator",
- root_build_dir),
+ _generator_dir = get_label_info(
+ ":v8_context_snapshot_generator($v8_snapshot_toolchain)",
+ "root_out_dir")
+ if (v8_win_cross_compile_using_wine) {
+ _generator_bin = "./" + rebase_path(
+ _generator_dir + "/v8_context_snapshot_generator.exe",
+ root_build_dir)
+ } else {
+ _generator_bin = "./" + rebase_path(
+ _generator_dir + "/v8_context_snapshot_generator",
+ root_build_dir)
+ }
+
+ args = []
+ if (v8_win_cross_compile_using_wine) {
+ assert(v8_wine_path != "",
+ "v8_wine_path must be set when v8_win_cross_compile_using_wine is true")
+ args += [ v8_wine_path ]
+ }
+ args += [
+ _generator_bin,
"--snapshot_blob=$snapshot_blob_path",
"--output_file=$output_path",
]

View File

@@ -1,3 +1,6 @@
chore_allow_customizing_microtask_policy_per_context.patch
build_warn_instead_of_abort_on_builtin_pgo_profile_mismatch.patch
feat_support_running_mksnapshot_exe_via_wine_for_windows.patch
fix_emit_win64_pdata_xdata_for_embedded_builtins_when.patch
fix_use_clang_x64_v8_arm64_snapshot_toolchain_for_win-arm64_on.patch
fix_use_zu_for_size_t_in_arm64_emitunwinddata_snprintf.patch
fix_derive_v8_control_flow_integrity_from_target_os_not.patch

View File

@@ -1,113 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: John Kleinschmidt <kleinschmidtorama@gmail.com>
Date: Tue, 24 Mar 2026 16:29:55 -0400
Subject: feat: support running mksnapshot.exe via Wine for Windows
cross-compile
When v8_win_cross_compile_using_wine=true is set, mksnapshot is built as a
Windows .exe using the target toolchain and executed via Wine on the Linux
host. This avoids needing source-level cross-compile patches for the
unwinding info code paths.
diff --git a/BUILD.gn b/BUILD.gn
index 751265ba83c04f0c545248a71b35e46034bfc90a..9ca41b06b569c729496abde7cba085518a9f0d71 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -2699,7 +2699,11 @@ template("run_mksnapshot") {
suffix = "_$name"
}
action("run_mksnapshot_" + name) {
- deps = [ ":mksnapshot($v8_snapshot_toolchain)" ]
+ if (v8_prebuilt_mksnapshot != "") {
+ deps = []
+ } else {
+ deps = [ ":mksnapshot($v8_snapshot_toolchain)" ]
+ }
if (v8_verify_deterministic_mksnapshot) {
# We archive the snapshot executable when verifying snapshot
# determinism to ease debugging.
@@ -2753,10 +2757,26 @@ template("run_mksnapshot") {
data += [ "$root_out_dir/mksnapshot_output${suffix}.log" ]
}
+ if (v8_prebuilt_mksnapshot != "") {
+ _mksnapshot_bin = v8_prebuilt_mksnapshot
+ } else {
+ _mksnapshot_dir =
+ get_label_info(":mksnapshot($v8_snapshot_toolchain)", "root_out_dir")
+ if (v8_win_cross_compile_using_wine) {
+ _mksnapshot_bin = _mksnapshot_dir + "/mksnapshot.exe"
+ } else {
+ _mksnapshot_bin = _mksnapshot_dir + "/mksnapshot"
+ }
+ }
+
+ if (v8_win_cross_compile_using_wine) {
+ assert(
+ v8_wine_path != "",
+ "v8_wine_path must be set when v8_win_cross_compile_using_wine is true")
+ args += [ v8_wine_path ]
+ }
args += [
- "./" + rebase_path(get_label_info(":mksnapshot($v8_snapshot_toolchain)",
- "root_out_dir") + "/mksnapshot",
- root_build_dir),
+ "./" + rebase_path(_mksnapshot_bin, root_build_dir),
"--turbo_instruction_scheduling",
"--turbo-always-optimize-spills",
diff --git a/gni/snapshot_toolchain.gni b/gni/snapshot_toolchain.gni
index 37ed262640d048a6fa5923279ae0388c1c0ae766..d9830914f0abd919143f0cf8b3069c5a3f70516e 100644
--- a/gni/snapshot_toolchain.gni
+++ b/gni/snapshot_toolchain.gni
@@ -32,6 +32,21 @@ declare_args() {
# toolchain that matches the bit-width of the target CPU, but runs on
# the host.
v8_snapshot_toolchain = ""
+
+ # When cross-compiling for Windows on a non-Windows host, build mksnapshot
+ # as a Windows .exe and run it via Wine instead of building a host-native
+ # mksnapshot with cross-compile patches.
+ v8_win_cross_compile_using_wine = false
+
+ # Absolute path to the wine64 binary. Required when
+ # v8_win_cross_compile_using_wine is true.
+ v8_wine_path = ""
+
+ # Path to a pre-built mksnapshot binary to use instead of building one from
+ # source. When set, run_mksnapshot will use this binary directly and skip
+ # building the mksnapshot target. The path should be absolute or relative
+ # to the source root.
+ v8_prebuilt_mksnapshot = ""
}
# Try to infer the appropriate snapshot toolchain for the v8_current_cpu
@@ -69,7 +84,12 @@ if (v8_snapshot_toolchain == "") {
# Cross-build from same ISA on one OS to another. For example:
# * targeting win/x64 on a linux/x64 host
# * targeting win/arm64 on a mac/arm64 host
- v8_snapshot_toolchain = host_toolchain
+ if (v8_win_cross_compile_using_wine && is_win && host_os != "win") {
+ # Build mksnapshot as a Windows .exe and run it via Wine.
+ v8_snapshot_toolchain = current_toolchain
+ } else {
+ v8_snapshot_toolchain = host_toolchain
+ }
} else if (host_cpu == "arm64" && current_cpu == "x64") {
# Cross-build from arm64 to intel (likely on an Apple Silicon mac).
v8_snapshot_toolchain =
@@ -119,7 +139,13 @@ assert(v8_snapshot_toolchain != "",
# We reuse the snapshot toolchain for building torque and other generators to
# avoid building v8_libbase on the host more than once. On mips with big endian,
# the snapshot toolchain is the target toolchain and, hence, can't be used.
-v8_generator_toolchain = v8_snapshot_toolchain
+# When using Wine for cross-compilation, mksnapshot is built as a Windows .exe
+# but other generators (torque, etc.) must still be host-native binaries.
+if (v8_win_cross_compile_using_wine && is_win && host_os != "win") {
+ v8_generator_toolchain = host_toolchain
+} else {
+ v8_generator_toolchain = v8_snapshot_toolchain
+}
if (host_cpu == "x64" && v8_current_cpu == "mips64") {
v8_generator_toolchain = "//build/toolchain/linux:clang_x64"
}

View File

@@ -0,0 +1,58 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Sam Attard <sattard@anthropic.com>
Date: Wed, 8 Apr 2026 05:07:17 +0000
Subject: fix: derive v8_control_flow_integrity from target_os, not
arm_control_flow_integrity
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
arm_control_flow_integrity is set in //build/config/arm.gni based on
is_linux/is_android (i.e. current_os). v8_control_flow_integrity then
uses 'arm_control_flow_integrity != none' to decide whether the
macro-assembler should emit pacibsp/autibsp/bti into generated code.
That breaks when the snapshot toolchain's current_os differs from the
real target — e.g. building win-arm64 on Linux, where mksnapshot is
//build/toolchain/linux:clang_x64_v8_arm64 (current_os=linux,
target_os=win). The snapshot toolchain sees arm_control_flow_integrity=
standard and bakes PAC into the embedded builtins, while the win-arm64
runtime is built with v8_control_flow_integrity=false. The runtime's
PointerAuthentication helpers are then no-ops, a PAC-signed LR flows
through unstripped, and the next autibsp in a code-range-copied builtin
fast-fails with FAST_FAIL_POINTER_AUTH_INVALID_RETURN_ADDRESS.
Key the non-simulator clause on target_os directly (the same OSes
arm.gni would enable CFI for), which is global and therefore identical
in every toolchain. No behaviour change for native Linux/Android arm64,
mac, or native Windows-hosted win-arm64.
diff --git a/BUILD.gn b/BUILD.gn
index bf8793c24a1146d39692ef7103a9c54b8d61d509..184b43f74dc6fa3212c0915cecf5b832a34179eb 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -345,9 +345,21 @@ declare_args() {
# ARM64. Enable it by default for simulator builds and when native code
# supports it as well. On Mac, control-flow integrity does not work so we
# avoid enabling it when using the simulator.
- v8_control_flow_integrity = v8_current_cpu == "arm64" &&
- ((v8_target_is_simulator && target_os != "mac") ||
- arm_control_flow_integrity != "none")
+ #
+ # The non-simulator clause checks target_os directly rather than
+ # arm_control_flow_integrity (which is keyed on current_os via is_linux /
+ # is_android in //build/config/arm.gni). This keeps the value consistent
+ # between the target toolchain and the snapshot toolchain when
+ # cross-compiling — e.g. building win-arm64 on a Linux host where the
+ # snapshot toolchain (//build/toolchain/linux:clang_x64_v8_arm64) has
+ # current_os == "linux" but target_os == "win". Otherwise mksnapshot bakes
+ # pacibsp/autibsp into the embedded builtins while the runtime is built
+ # without V8_ENABLE_CONTROL_FLOW_INTEGRITY, and the resulting binary
+ # fast-fails with FAST_FAIL_POINTER_AUTH_INVALID_RETURN_ADDRESS.
+ v8_control_flow_integrity =
+ v8_current_cpu == "arm64" &&
+ ((v8_target_is_simulator && target_os != "mac") ||
+ target_os == "android" || target_os == "linux")
# Enable heap reservation of size 4GB. Only possible for 64bit archs.
cppgc_enable_caged_heap =

View File

@@ -0,0 +1,815 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Sam Attard <sattard@anthropic.com>
Date: Wed, 8 Apr 2026 00:46:31 +0000
Subject: fix: emit Win64 .pdata/.xdata for embedded builtins when
cross-compiling
V8's embedded-builtins unwind-info path (XdataEncoder in the assembler,
SetBuiltinUnwindData on Isolate, EmitUnwindData in the embedded file
writer) is gated on V8_OS_WIN64, which derives from the *host* V8_OS_WIN
set by v8config.h. When mksnapshot is built for a non-Windows host while
targeting Windows, V8_OS_WIN is undefined, so the entire generation path
is compiled out and embedded.S contains no .pdata/.xdata for the
builtins blob. The resulting electron.exe has no RUNTIME_FUNCTION
records for V8 builtins, so Crashpad/ETW stack walks through builtins
truncate.
Introduce V8_TARGET_OS_WIN64/_X64/_ARM64 keyed on V8_TARGET_OS_WIN, and
re-gate only the *generation* half (assembler hooks, BuiltinUnwindInfo
collection, GetUnwindInfoForBuiltinFunctions, the embedded-file-writer
emit path, BUILD.gn source inclusion) on the target macros. Leave the
*runtime registration* half (RtlAddFunctionTable, the
CrashForExceptionInNonABICompliantCodeRange handler body,
RegisterNonABICompliantCodeRange, CodeRangeUnwindingRecord) on the host
V8_OS_WIN64, since that code needs <windows.h> and runs in the target
process. Define UNW_FLAG_EHANDLER locally so V8UnwindData compiles
without <winnt.h>.
Also fix two further host-vs-target mismatches that affect codegen when
mksnapshot runs on a non-Windows host:
- ia32 MacroAssembler::AllocateStackSpace was V8_OS_WIN-gated, so the
Windows guard-page stack-probing loop was dropped from win-x86
builtins. The x64 and arm64 equivalents already use V8_TARGET_OS_WIN.
- arm64 MacroAssembler::Printf's varargs ABI selection (float varargs in
x0-x7 on Windows-arm64) was V8_OS_WIN-gated.
On a native Windows build both macro families are defined and behaviour
is unchanged.
diff --git a/BUILD.gn b/BUILD.gn
index 751265ba83c04f0c545248a71b35e46034bfc90a..bf8793c24a1146d39692ef7103a9c54b8d61d509 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -5033,7 +5033,7 @@ v8_header_set("v8_internal_headers") {
"third_party/valgrind/valgrind.h",
]
- if (is_win) {
+ if (is_win || target_os == "win") {
sources += [ "src/diagnostics/unwinding-info-win64.h" ]
}
@@ -5126,7 +5126,7 @@ v8_header_set("v8_internal_headers") {
sources += [ "src/trap-handler/trap-handler-simulator.h" ]
}
}
- if (is_win) {
+ if (is_win || target_os == "win") {
sources += [ "src/diagnostics/unwinding-info-win64.h" ]
}
} else if (v8_current_cpu == "mips64" || v8_current_cpu == "mips64el") {
@@ -6531,7 +6531,7 @@ v8_cluster_source_set("v8_base_without_compiler") {
"src/regexp/x64/regexp-macro-assembler-x64.cc",
]
- if (is_win) {
+ if (is_win || target_os == "win") {
sources += [ "src/diagnostics/unwinding-info-win64.cc" ]
}
@@ -6607,7 +6607,7 @@ v8_cluster_source_set("v8_base_without_compiler") {
sources += [ "src/trap-handler/handler-outside-simulator.cc" ]
}
}
- if (is_win) {
+ if (is_win || target_os == "win") {
sources += [ "src/diagnostics/unwinding-info-win64.cc" ]
}
} else if (v8_current_cpu == "mips64" || v8_current_cpu == "mips64el") {
diff --git a/src/builtins/arm64/builtins-arm64.cc b/src/builtins/arm64/builtins-arm64.cc
index f3c787d701fd1f9421220717cec1228ffc049a80..4d36d1b931634d07eb2d4f71f3a7380ea5016978 100644
--- a/src/builtins/arm64/builtins-arm64.cc
+++ b/src/builtins/arm64/builtins-arm64.cc
@@ -39,9 +39,9 @@
#include "src/wasm/wasm-objects.h"
#endif // V8_ENABLE_WEBASSEMBLY
-#if defined(V8_OS_WIN)
+#if defined(V8_TARGET_OS_WIN)
#include "src/diagnostics/unwinding-info-win64.h"
-#endif // V8_OS_WIN
+#endif // V8_TARGET_OS_WIN
namespace v8 {
namespace internal {
@@ -642,7 +642,7 @@ void Generate_JSEntryVariant(MacroAssembler* masm, StackFrame::Type type,
{
NoRootArrayScope no_root_array(masm);
-#if defined(V8_OS_WIN)
+#if defined(V8_TARGET_OS_WIN)
// In order to allow Windows debugging tools to reconstruct a call stack, we
// must generate information describing how to recover at least fp, sp, and
// pc for the calling frame. Here, JSEntry registers offsets to
diff --git a/src/builtins/setup-builtins-internal.cc b/src/builtins/setup-builtins-internal.cc
index e8f8a1138ea4de84f4348d12531b0b6042b19533..6c399eddacc36f39a7f7e8ab78feeb4a97b16d08 100644
--- a/src/builtins/setup-builtins-internal.cc
+++ b/src/builtins/setup-builtins-internal.cc
@@ -227,9 +227,9 @@ V8_NOINLINE Tagged<Code> BuildWithMacroAssembler(
.set_self_reference(masm.CodeObject())
.set_builtin(builtin)
.Build();
-#if defined(V8_OS_WIN64)
+#if defined(V8_TARGET_OS_WIN64)
isolate->SetBuiltinUnwindData(builtin, masm.GetUnwindInfo());
-#endif // V8_OS_WIN64
+#endif // V8_TARGET_OS_WIN64
return *code;
}
diff --git a/src/codegen/arm64/assembler-arm64.cc b/src/codegen/arm64/assembler-arm64.cc
index 40adf1773e658e5bfe5f40f503421a3320c49f7b..1583d4de4ca8b3968834401a8148367d12fdccd5 100644
--- a/src/codegen/arm64/assembler-arm64.cc
+++ b/src/codegen/arm64/assembler-arm64.cc
@@ -421,7 +421,7 @@ Assembler::Assembler(const MaybeAssemblerZone& zone,
constpool_(this) {
Reset();
-#if defined(V8_OS_WIN)
+#if defined(V8_TARGET_OS_WIN)
if (options.collect_win64_unwind_info) {
xdata_encoder_ = std::make_unique<win64_unwindinfo::XdataEncoder>(*this);
}
@@ -449,7 +449,7 @@ void Assembler::Reset() {
next_veneer_pool_check_ = kMaxInt;
}
-#if defined(V8_OS_WIN)
+#if defined(V8_TARGET_OS_WIN)
win64_unwindinfo::BuiltinUnwindInfo Assembler::GetUnwindInfo() const {
DCHECK(options().collect_win64_unwind_info);
DCHECK_NOT_NULL(xdata_encoder_);
@@ -1433,7 +1433,7 @@ void Assembler::stp(const CPURegister& rt, const CPURegister& rt2,
const MemOperand& dst) {
LoadStorePair(rt, rt2, dst, StorePairOpFor(rt, rt2));
-#if defined(V8_OS_WIN)
+#if defined(V8_TARGET_OS_WIN)
if (xdata_encoder_ && rt == x29 && rt2 == lr && dst.base().IsSP()) {
xdata_encoder_->onSaveFpLr();
}
diff --git a/src/codegen/arm64/assembler-arm64.h b/src/codegen/arm64/assembler-arm64.h
index a642a62f96a9748782b691a92ee5aecfe3d75b32..a3234c51322b8e3d620f996cb570333a7e6efa1e 100644
--- a/src/codegen/arm64/assembler-arm64.h
+++ b/src/codegen/arm64/assembler-arm64.h
@@ -27,9 +27,9 @@
#undef mvn
#endif
-#if defined(V8_OS_WIN)
+#if defined(V8_TARGET_OS_WIN)
#include "src/diagnostics/unwinding-info-win64.h"
-#endif // V8_OS_WIN
+#endif // V8_TARGET_OS_WIN
namespace v8 {
namespace internal {
@@ -3200,7 +3200,7 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
DISALLOW_IMPLICIT_CONSTRUCTORS(BlockPoolsScope);
};
-#if defined(V8_OS_WIN)
+#if defined(V8_TARGET_OS_WIN)
win64_unwindinfo::XdataEncoder* GetXdataEncoder() {
return xdata_encoder_.get();
}
@@ -3531,7 +3531,7 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
// enabled.
JumpTableInfoWriter jump_table_info_writer_;
-#if defined(V8_OS_WIN)
+#if defined(V8_TARGET_OS_WIN)
std::unique_ptr<win64_unwindinfo::XdataEncoder> xdata_encoder_;
#endif
diff --git a/src/codegen/arm64/macro-assembler-arm64.cc b/src/codegen/arm64/macro-assembler-arm64.cc
index a20c06e326c13d2965b217718c0df0c45784b286..f8e022fb66e42855cc33d8e4de07393025533a92 100644
--- a/src/codegen/arm64/macro-assembler-arm64.cc
+++ b/src/codegen/arm64/macro-assembler-arm64.cc
@@ -4552,7 +4552,7 @@ void MacroAssembler::PrintfNoPreserve(const char* format,
// Copies of the printf vararg registers that we can pop from.
CPURegList pcs_varargs = kPCSVarargs;
-#ifndef V8_OS_WIN
+#ifndef V8_TARGET_OS_WIN
CPURegList pcs_varargs_fp = kPCSVarargsFP;
#endif
@@ -4569,7 +4569,7 @@ void MacroAssembler::PrintfNoPreserve(const char* format,
if (args[i].Is32Bits()) pcs[i] = pcs[i].W();
} else if (args[i].IsVRegister()) {
// In C, floats are always cast to doubles for varargs calls.
-#ifdef V8_OS_WIN
+#ifdef V8_TARGET_OS_WIN
// In case of variadic functions SIMD and Floating-point registers
// aren't used. The general x0-x7 should be used instead.
// https://docs.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions
@@ -4607,7 +4607,7 @@ void MacroAssembler::PrintfNoPreserve(const char* format,
// Do a second pass to move values into their final positions and perform any
// conversions that may be required.
for (int i = 0; i < arg_count; i++) {
-#ifdef V8_OS_WIN
+#ifdef V8_TARGET_OS_WIN
if (args[i].IsVRegister()) {
if (pcs[i].SizeInBytes() != args[i].SizeInBytes()) {
// If the argument is half- or single-precision
diff --git a/src/codegen/ia32/macro-assembler-ia32.cc b/src/codegen/ia32/macro-assembler-ia32.cc
index ce1b803cf691f17cdcf17cc950a87f557b1be3b5..e779ee79503797c4c6556606471e3c2bb6dbac7b 100644
--- a/src/codegen/ia32/macro-assembler-ia32.cc
+++ b/src/codegen/ia32/macro-assembler-ia32.cc
@@ -1076,7 +1076,7 @@ void MacroAssembler::LeaveFrame(StackFrame::Type type) {
leave();
}
-#ifdef V8_OS_WIN
+#ifdef V8_TARGET_OS_WIN
void MacroAssembler::AllocateStackSpace(Register bytes_scratch) {
ASM_CODE_COMMENT(this);
// In windows, we cannot increment the stack size by more than one page
diff --git a/src/codegen/ia32/macro-assembler-ia32.h b/src/codegen/ia32/macro-assembler-ia32.h
index 77333472ebf6dbf4ee2b1f44466ce2110c9e97cd..992391f5138cfb8471f4100ee8be761331462737 100644
--- a/src/codegen/ia32/macro-assembler-ia32.h
+++ b/src/codegen/ia32/macro-assembler-ia32.h
@@ -96,7 +96,7 @@ class V8_EXPORT_PRIVATE MacroAssembler
// stack check, do it before calling this function because this function may
// write into the newly allocated space. It may also overwrite the given
// register's value, in the version that takes a register.
-#ifdef V8_OS_WIN
+#ifdef V8_TARGET_OS_WIN
void AllocateStackSpace(Register bytes_scratch);
void AllocateStackSpace(int bytes);
#else
diff --git a/src/codegen/x64/assembler-x64.cc b/src/codegen/x64/assembler-x64.cc
index 6edc61b4d52f8d4e9019c4057b5a5d4b8ea7b4fe..13fd6d119486a56783a5673867cf09692929834e 100644
--- a/src/codegen/x64/assembler-x64.cc
+++ b/src/codegen/x64/assembler-x64.cc
@@ -446,7 +446,7 @@ Assembler::Assembler(const AssemblerOptions& options,
EnableCpuFeature(SSE3);
}
-#if defined(V8_OS_WIN_X64)
+#if defined(V8_TARGET_OS_WIN_X64)
if (options.collect_win64_unwind_info) {
xdata_encoder_ = std::make_unique<win64_unwindinfo::XdataEncoder>(*this);
}
@@ -532,7 +532,7 @@ void Assembler::FinalizeJumpOptimizationInfo() {
}
}
-#if defined(V8_OS_WIN_X64)
+#if defined(V8_TARGET_OS_WIN_X64)
win64_unwindinfo::BuiltinUnwindInfo Assembler::GetUnwindInfo() const {
DCHECK(options().collect_win64_unwind_info);
DCHECK_NOT_NULL(xdata_encoder_);
@@ -1991,7 +1991,7 @@ void Assembler::emit_mov(Register dst, Register src, int size) {
emit(0x8B);
emit_modrm(dst, src);
-#if defined(V8_OS_WIN_X64)
+#if defined(V8_TARGET_OS_WIN_X64)
if (xdata_encoder_ && dst == rbp && src == rsp) {
xdata_encoder_->onMovRbpRsp();
}
@@ -2437,7 +2437,7 @@ void Assembler::pushq(Register src) {
emit_optional_rex_32(src);
emit(0x50 | src.low_bits());
-#if defined(V8_OS_WIN_X64)
+#if defined(V8_TARGET_OS_WIN_X64)
if (xdata_encoder_ && src == rbp) {
xdata_encoder_->onPushRbp();
}
@@ -4920,7 +4920,7 @@ void Assembler::pushpq(Register src) {
EnsureSpace ensure_space(this);
emit_rex2_64(src, kRex2Map0);
emit(0x50 | src.low_bits());
-#if defined(V8_OS_WIN_X64)
+#if defined(V8_TARGET_OS_WIN_X64)
if (xdata_encoder_ && src == rbp) {
xdata_encoder_->onPushRbp();
}
@@ -4935,7 +4935,7 @@ void Assembler::push2q(Register src1, Register src2) {
kW0, kFlagUpdate, kNewDataDest);
emit(0xFF);
emit_modrm(6, src2);
-#if defined(V8_OS_WIN_X64)
+#if defined(V8_TARGET_OS_WIN_X64)
if (xdata_encoder_ && src1 == rbp) {
xdata_encoder_->onPushRbp();
}
@@ -4953,7 +4953,7 @@ void Assembler::push2pq(Register src1, Register src2) {
kW1, kFlagUpdate, kNewDataDest);
emit(0xFF);
emit_modrm(6, src2);
-#if defined(V8_OS_WIN_X64)
+#if defined(V8_TARGET_OS_WIN_X64)
if (xdata_encoder_ && src1 == rbp) {
xdata_encoder_->onPushRbp();
}
diff --git a/src/codegen/x64/assembler-x64.h b/src/codegen/x64/assembler-x64.h
index a4aaae402920d90e961e163cf87af5c564c28a78..51098680c01df93dca361816020eb9fb6cf5c211 100644
--- a/src/codegen/x64/assembler-x64.h
+++ b/src/codegen/x64/assembler-x64.h
@@ -53,7 +53,7 @@
#include "src/codegen/x64/sse-instr.h"
#include "src/objects/smi.h"
-#if defined(V8_OS_WIN_X64)
+#if defined(V8_TARGET_OS_WIN_X64)
#include "src/diagnostics/unwinding-info-win64.h"
#endif
@@ -2687,7 +2687,7 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
uint8_t byte_at(int pos) { return buffer_start_[pos]; }
void set_byte_at(int pos, uint8_t value) { buffer_start_[pos] = value; }
-#if defined(V8_OS_WIN_X64)
+#if defined(V8_TARGET_OS_WIN_X64)
win64_unwindinfo::BuiltinUnwindInfo GetUnwindInfo() const;
#endif
@@ -3557,7 +3557,7 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
JumpTableInfoWriter builtin_jump_table_info_writer_;
-#if defined(V8_OS_WIN_X64)
+#if defined(V8_TARGET_OS_WIN_X64)
std::unique_ptr<win64_unwindinfo::XdataEncoder> xdata_encoder_;
#endif
};
diff --git a/src/common/globals.h b/src/common/globals.h
index d5885006fca0b8fb78c71f833e054e18ba934731..fa4bf10799662137d876d5c4d870882638306658 100644
--- a/src/common/globals.h
+++ b/src/common/globals.h
@@ -340,6 +340,22 @@ const size_t kShortBuiltinCallsOldSpaceSizeThreshold = size_t{2} * GB;
#define V8_OS_WIN64 true
#endif
+// Like V8_OS_WIN_X64/ARM64/64 above, but keyed on the *target* OS rather than
+// the host. mksnapshot uses these to decide whether to collect and emit
+// Windows .pdata/.xdata for the embedded builtins blob when cross-compiling
+// for Windows on a non-Windows host (where V8_OS_WIN64 is undefined).
+#if defined(V8_TARGET_OS_WIN) && defined(V8_TARGET_ARCH_X64)
+#define V8_TARGET_OS_WIN_X64 true
+#endif
+
+#if defined(V8_TARGET_OS_WIN) && defined(V8_TARGET_ARCH_ARM64)
+#define V8_TARGET_OS_WIN_ARM64 true
+#endif
+
+#if defined(V8_TARGET_OS_WIN_X64) || defined(V8_TARGET_OS_WIN_ARM64)
+#define V8_TARGET_OS_WIN64 true
+#endif
+
// Support for floating point parameters in calls to C.
// It's currently enabled only for the platforms listed below. We don't plan
// to add support for IA32, because it has a totally different approach
diff --git a/src/diagnostics/unwinding-info-win64.cc b/src/diagnostics/unwinding-info-win64.cc
index 1312609e5b648fdca187373c374126282c7afa77..3655b3b344aa9d978c93ff4568cd8a2260014853 100644
--- a/src/diagnostics/unwinding-info-win64.cc
+++ b/src/diagnostics/unwinding-info-win64.cc
@@ -7,19 +7,28 @@
#include "src/codegen/macro-assembler.h"
#include "src/utils/allocation.h"
-#if defined(V8_OS_WIN_X64)
+#if defined(V8_TARGET_OS_WIN_X64)
#include "src/codegen/x64/assembler-x64.h"
-#elif defined(V8_OS_WIN_ARM64)
+#elif defined(V8_TARGET_OS_WIN_ARM64)
#include "src/codegen/arm64/assembler-arm64-inl.h"
#include "src/codegen/arm64/macro-assembler-arm64-inl.h"
#else
#error "Unsupported OS"
-#endif // V8_OS_WIN_X64
+#endif // V8_TARGET_OS_WIN_X64
+#if defined(V8_OS_WIN64)
#include <windows.h>
// This has to come after windows.h.
#include <versionhelpers.h> // For IsWindows8OrGreater().
+#endif // V8_OS_WIN64
+
+// UNW_FLAG_EHANDLER is normally provided by <winnt.h>; define it locally so
+// the xdata structs below also compile in mksnapshot when cross-compiling on
+// a non-Windows host.
+#ifndef UNW_FLAG_EHANDLER
+#define UNW_FLAG_EHANDLER 0x01
+#endif
namespace v8 {
namespace internal {
@@ -27,6 +36,8 @@ namespace win64_unwindinfo {
bool CanEmitUnwindInfoForBuiltins() { return v8_flags.win64_unwinding_info; }
+#if defined(V8_OS_WIN64)
+
bool CanRegisterUnwindInfoForNonABICompliantCodeRange() {
return !v8_flags.jitless;
}
@@ -61,7 +72,9 @@ extern "C" __declspec(dllexport) int CRASH_HANDLER_FUNCTION_NAME(
return ExceptionContinueSearch;
}
-#if defined(V8_OS_WIN_X64)
+#endif // V8_OS_WIN64
+
+#if defined(V8_TARGET_OS_WIN_X64)
#pragma pack(push, 1)
@@ -88,7 +101,6 @@ struct UNWIND_INFO {
};
static constexpr int kNumberOfUnwindCodes = 2;
-static constexpr int kMaxExceptionThunkSize = 12;
struct V8UnwindData {
UNWIND_INFO unwind_info;
@@ -115,6 +127,10 @@ struct V8UnwindData {
}
};
+#if defined(V8_OS_WIN64)
+
+static constexpr int kMaxExceptionThunkSize = 12;
+
struct ExceptionHandlerUnwindData {
UNWIND_INFO unwind_info;
@@ -145,6 +161,8 @@ struct ExceptionHandlerRecord {
uint8_t exception_thunk[kMaxExceptionThunkSize];
};
+#endif // V8_OS_WIN64
+
#pragma pack(pop)
std::vector<uint8_t> GetUnwindInfoForBuiltinFunctions() {
@@ -154,6 +172,8 @@ std::vector<uint8_t> GetUnwindInfoForBuiltinFunctions() {
reinterpret_cast<uint8_t*>(&xdata) + sizeof(xdata));
}
+#if defined(V8_OS_WIN64)
+
template <typename Record>
void InitUnwindingRecord(Record* record, size_t code_size_in_bytes) {
// We assume that the first page of the code range is executable and
@@ -180,7 +200,9 @@ void InitUnwindingRecord(Record* record, size_t code_size_in_bytes) {
masm.instruction_size());
}
-#elif defined(V8_OS_WIN_ARM64)
+#endif // V8_OS_WIN64
+
+#elif defined(V8_TARGET_OS_WIN_ARM64)
#pragma pack(push, 1)
@@ -220,7 +242,6 @@ struct UNWIND_INFO {
};
static constexpr int kDefaultNumberOfUnwindCodeWords = 1;
-static constexpr int kMaxExceptionThunkSize = 16;
static constexpr int kFunctionLengthShiftSize = 2;
static constexpr int kFunctionLengthMask = (1 << kFunctionLengthShiftSize) - 1;
static constexpr int kAllocStackShiftSize = 4;
@@ -299,6 +320,10 @@ struct V8UnwindData {
}
};
+#if defined(V8_OS_WIN64)
+
+static constexpr int kMaxExceptionThunkSize = 16;
+
struct CodeRangeUnwindingRecord {
void* dynamic_table;
uint32_t runtime_function_count;
@@ -319,6 +344,8 @@ struct CodeRangeUnwindingRecord {
RUNTIME_FUNCTION runtime_function[kDefaultRuntimeFunctionCount];
};
+#endif // V8_OS_WIN64
+
#pragma pack(pop)
FrameOffsets::FrameOffsets()
@@ -383,6 +410,8 @@ std::vector<uint8_t> GetUnwindInfoForBuiltinFunction(
&xdata.unwind_codes[xdata.unwind_info.CodeWords]));
}
+#if defined(V8_OS_WIN64)
+
template <typename Record>
void InitUnwindingRecord(Record* record, size_t code_size_in_bytes) {
// We assume that the first page of the code range is executable and
@@ -459,7 +488,11 @@ void InitUnwindingRecord(Record* record, size_t code_size_in_bytes) {
masm.instruction_size());
}
-#endif // V8_OS_WIN_X64
+#endif // V8_OS_WIN64
+
+#endif // V8_TARGET_OS_WIN_X64
+
+#if defined(V8_OS_WIN64)
namespace {
@@ -604,7 +637,9 @@ void UnregisterNonABICompliantCodeRange(void* start) {
}
}
-#if defined(V8_OS_WIN_X64)
+#endif // V8_OS_WIN64
+
+#if defined(V8_TARGET_OS_WIN_X64)
void XdataEncoder::onPushRbp() {
current_frame_code_offset_ =
@@ -618,7 +653,7 @@ void XdataEncoder::onMovRbpRsp() {
}
}
-#elif defined(V8_OS_WIN_ARM64)
+#elif defined(V8_TARGET_OS_WIN_ARM64)
void XdataEncoder::onSaveFpLr() {
current_frame_code_offset_ = assembler_.pc_offset() - 4;
@@ -633,7 +668,7 @@ void XdataEncoder::onFramePointerAdjustment(int fp_to_saved_caller_fp,
current_frame_adjustment_.fp_to_caller_sp = fp_to_caller_sp;
}
-#endif // V8_OS_WIN_X64
+#endif // V8_TARGET_OS_WIN_X64
} // namespace win64_unwindinfo
} // namespace internal
diff --git a/src/diagnostics/unwinding-info-win64.h b/src/diagnostics/unwinding-info-win64.h
index bb32f49e5d8966bafc079d274ad9600f75f85759..54906f76fbe06fef08a4668faee1fc46b5699ff4 100644
--- a/src/diagnostics/unwinding-info-win64.h
+++ b/src/diagnostics/unwinding-info-win64.h
@@ -11,8 +11,7 @@
#include "include/v8config.h"
#include "src/common/globals.h"
-#if defined(V8_OS_WIN64)
-#include "src/base/win32-headers.h"
+#if defined(V8_TARGET_OS_WIN64)
namespace v8 {
namespace internal {
@@ -32,6 +31,7 @@ static const int kOSPageSize = 4096;
*/
bool CanEmitUnwindInfoForBuiltins();
+#if defined(V8_OS_WIN64)
/**
* Returns true if V8 if we can register unwinding data for the whole code range
* of an isolate or Wasm module. The first page of the code range is reserved
@@ -50,6 +50,7 @@ void SetUnhandledExceptionCallback(
void RegisterNonABICompliantCodeRange(void* start, size_t size_in_bytes);
void UnregisterNonABICompliantCodeRange(void* start);
+#endif // V8_OS_WIN64
/**
* Default count of RUNTIME_FUNCTION needed. For Windows X64, 1 RUNTIME_FUNCTION
@@ -61,7 +62,7 @@ void UnregisterNonABICompliantCodeRange(void* start);
*/
static const uint32_t kDefaultRuntimeFunctionCount = 1;
-#if defined(V8_OS_WIN_X64)
+#if defined(V8_TARGET_OS_WIN_X64)
static const int kPushRbpInstructionLength = 1;
static const int kMovRbpRspInstructionLength = 3;
@@ -107,7 +108,7 @@ class XdataEncoder {
int current_frame_code_offset_;
};
-#elif defined(V8_OS_WIN_ARM64)
+#elif defined(V8_TARGET_OS_WIN_ARM64)
/**
* Base on below doc, unwind record has 18 bits (unsigned) to encode function
@@ -182,6 +183,6 @@ class XdataEncoder {
} // namespace internal
} // namespace v8
-#endif // V8_OS_WIN64
+#endif // V8_TARGET_OS_WIN64
#endif // V8_DIAGNOSTICS_UNWINDING_INFO_WIN64_H_
diff --git a/src/execution/isolate.cc b/src/execution/isolate.cc
index 6d8c9927b433e9be772065fd6993b5849640ae33..e360ba9d839469c4406be300ed48fbe5955657e5 100644
--- a/src/execution/isolate.cc
+++ b/src/execution/isolate.cc
@@ -170,9 +170,9 @@
#include "src/diagnostics/etw-jit-win.h"
#endif // V8_ENABLE_ETW_STACK_WALKING
-#if defined(V8_OS_WIN64)
+#if defined(V8_TARGET_OS_WIN64)
#include "src/diagnostics/unwinding-info-win64.h"
-#endif // V8_OS_WIN64
+#endif // V8_TARGET_OS_WIN64
#if USE_SIMULATOR
#include "src/execution/simulator-base.h"
@@ -7276,7 +7276,7 @@ void Isolate::PrepareBuiltinSourcePositionMap() {
}
}
-#if defined(V8_OS_WIN64)
+#if defined(V8_TARGET_OS_WIN64)
void Isolate::SetBuiltinUnwindData(
Builtin builtin,
const win64_unwindinfo::BuiltinUnwindInfo& unwinding_info) {
@@ -7284,7 +7284,7 @@ void Isolate::SetBuiltinUnwindData(
embedded_file_writer_->SetBuiltinUnwindData(builtin, unwinding_info);
}
}
-#endif // V8_OS_WIN64
+#endif // V8_TARGET_OS_WIN64
void Isolate::SetPrepareStackTraceCallback(PrepareStackTraceCallback callback) {
prepare_stack_trace_callback_ = callback;
diff --git a/src/execution/isolate.h b/src/execution/isolate.h
index e11bb4083042e2b6fd4101eed0f0d06cae1b0ef1..6b02e13d4e5acceb976676b0dd0eb090e1e08ab5 100644
--- a/src/execution/isolate.h
+++ b/src/execution/isolate.h
@@ -190,9 +190,11 @@ class WasmRevecVerifier;
} // namespace turboshaft
} // namespace compiler
+#if defined(V8_TARGET_OS_WIN64)
namespace win64_unwindinfo {
class BuiltinUnwindInfo;
} // namespace win64_unwindinfo
+#endif // V8_TARGET_OS_WIN64
namespace metrics {
class Recorder;
@@ -2033,11 +2035,11 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory {
// annotate the builtin blob with debugging information.
void PrepareBuiltinSourcePositionMap();
-#if defined(V8_OS_WIN64)
+#if defined(V8_TARGET_OS_WIN64)
void SetBuiltinUnwindData(
Builtin builtin,
const win64_unwindinfo::BuiltinUnwindInfo& unwinding_info);
-#endif // V8_OS_WIN64
+#endif // V8_TARGET_OS_WIN64
void SetPrepareStackTraceCallback(PrepareStackTraceCallback callback);
MaybeDirectHandle<Object> RunPrepareStackTraceCallback(
diff --git a/src/snapshot/embedded/embedded-file-writer-interface.h b/src/snapshot/embedded/embedded-file-writer-interface.h
index 3d43baad83ceef8c03384473522c7c8ddb904081..fec1b47b96c9a68a4e2986f2f00a7d7288036c65 100644
--- a/src/snapshot/embedded/embedded-file-writer-interface.h
+++ b/src/snapshot/embedded/embedded-file-writer-interface.h
@@ -14,11 +14,11 @@ namespace internal {
class Builtins;
-#if defined(V8_OS_WIN64)
+#if defined(V8_TARGET_OS_WIN64)
namespace win64_unwindinfo {
class BuiltinUnwindInfo;
}
-#endif // V8_OS_WIN64
+#endif // V8_TARGET_OS_WIN64
static constexpr char kDefaultEmbeddedVariant[] = "Default";
@@ -40,11 +40,11 @@ class EmbeddedFileWriterInterface {
// compiled builtin InstructionStream objects with trampolines.
virtual void PrepareBuiltinSourcePositionMap(Builtins* builtins) = 0;
-#if defined(V8_OS_WIN64)
+#if defined(V8_TARGET_OS_WIN64)
virtual void SetBuiltinUnwindData(
Builtin builtin,
const win64_unwindinfo::BuiltinUnwindInfo& unwinding_info) = 0;
-#endif // V8_OS_WIN64
+#endif // V8_TARGET_OS_WIN64
};
} // namespace internal
diff --git a/src/snapshot/embedded/embedded-file-writer.cc b/src/snapshot/embedded/embedded-file-writer.cc
index 21a5abd275097bac4221686641b962a8c57c4a46..f93ab3c058ebfb3f886bd4a9ff45019971f5c856 100644
--- a/src/snapshot/embedded/embedded-file-writer.cc
+++ b/src/snapshot/embedded/embedded-file-writer.cc
@@ -193,7 +193,7 @@ void EmbeddedFileWriter::WriteFileEpilogue(PlatformEmbeddedFileWriterBase* w,
w->Newline();
}
-#if defined(V8_OS_WIN64)
+#if defined(V8_TARGET_OS_WIN64)
{
base::EmbeddedVector<char, kTemporaryStringLength> unwind_info_symbol;
base::SNPrintF(unwind_info_symbol, "%s_Builtins_UnwindInfo",
@@ -203,7 +203,7 @@ void EmbeddedFileWriter::WriteFileEpilogue(PlatformEmbeddedFileWriterBase* w,
EmbeddedBlobCodeSymbol().c_str(), blob,
reinterpret_cast<const void*>(&unwind_infos_[0]));
}
-#endif // V8_OS_WIN64
+#endif // V8_TARGET_OS_WIN64
w->FileEpilogue();
}
diff --git a/src/snapshot/embedded/embedded-file-writer.h b/src/snapshot/embedded/embedded-file-writer.h
index 40f22006041d930fedd133e03359b00c0fecff47..9cc61310aef9c7f9b722fd84a26e4c08c86fde44 100644
--- a/src/snapshot/embedded/embedded-file-writer.h
+++ b/src/snapshot/embedded/embedded-file-writer.h
@@ -17,9 +17,9 @@
#include "src/snapshot/embedded/embedded-file-writer-interface.h"
#include "src/snapshot/embedded/platform-embedded-file-writer-base.h"
-#if defined(V8_OS_WIN64)
+#if defined(V8_TARGET_OS_WIN64)
#include "src/diagnostics/unwinding-info-win64.h"
-#endif // V8_OS_WIN64
+#endif // V8_TARGET_OS_WIN64
namespace v8 {
namespace internal {
@@ -40,14 +40,14 @@ class EmbeddedFileWriter : public EmbeddedFileWriterInterface {
void PrepareBuiltinSourcePositionMap(Builtins* builtins) override;
-#if defined(V8_OS_WIN64)
+#if defined(V8_TARGET_OS_WIN64)
void SetBuiltinUnwindData(
Builtin builtin,
const win64_unwindinfo::BuiltinUnwindInfo& unwinding_info) override {
DCHECK_LT(static_cast<int>(builtin), Builtins::kBuiltinCount);
unwind_infos_[static_cast<int>(builtin)] = unwinding_info;
}
-#endif // V8_OS_WIN64
+#endif // V8_TARGET_OS_WIN64
void SetEmbeddedFile(const char* embedded_src_path) {
embedded_src_path_ = embedded_src_path;
@@ -186,9 +186,9 @@ class EmbeddedFileWriter : public EmbeddedFileWriterInterface {
std::vector<uint8_t> source_positions_[Builtins::kBuiltinCount];
std::vector<LabelInfo> label_info_[Builtins::kBuiltinCount];
-#if defined(V8_OS_WIN64)
+#if defined(V8_TARGET_OS_WIN64)
win64_unwindinfo::BuiltinUnwindInfo unwind_infos_[Builtins::kBuiltinCount];
-#endif // V8_OS_WIN64
+#endif // V8_TARGET_OS_WIN64
std::map<const char*, int> external_filenames_;
std::vector<const char*> external_filenames_by_index_;
diff --git a/src/snapshot/embedded/platform-embedded-file-writer-win.cc b/src/snapshot/embedded/platform-embedded-file-writer-win.cc
index bf76435717cf63f6f7be288c9b7e963c14b29425..b2319b9fea8b8ba8189ab577cbcf6982c3733bc0 100644
--- a/src/snapshot/embedded/platform-embedded-file-writer-win.cc
+++ b/src/snapshot/embedded/platform-embedded-file-writer-win.cc
@@ -8,7 +8,7 @@
#include "src/common/globals.h" // For V8_OS_WIN64
-#if defined(V8_OS_WIN64)
+#if defined(V8_TARGET_OS_WIN64)
#include "src/builtins/builtins.h"
#include "src/diagnostics/unwinding-info-win64.h"
#include "src/snapshot/embedded/embedded-data-inl.h"
@@ -59,7 +59,7 @@ namespace internal {
namespace {
-#if defined(V8_OS_WIN_X64)
+#if defined(V8_TARGET_OS_WIN_X64)
void WriteUnwindInfoEntry(PlatformEmbeddedFileWriterWin* w,
const char* unwind_info_symbol,
@@ -175,7 +175,7 @@ void EmitUnwindData(PlatformEmbeddedFileWriterWin* w,
w->Newline();
}
-#elif defined(V8_OS_WIN_ARM64)
+#elif defined(V8_TARGET_OS_WIN_ARM64)
void EmitUnwindData(PlatformEmbeddedFileWriterWin* w,
const char* unwind_info_symbol,
@@ -318,13 +318,13 @@ void PlatformEmbeddedFileWriterWin::MaybeEmitUnwindData(
const EmbeddedData* blob, const void* unwind_infos) {
// Windows ARM64 supports cross build which could require unwind info for
// host_os. Ignore this case because it is only used in build time.
-#if defined(V8_OS_WIN_ARM64)
+#if defined(V8_TARGET_OS_WIN_ARM64)
if (target_arch_ != EmbeddedTargetArch::kArm64) {
return;
}
#endif // V8_OS_WIN_ARM64
-#if defined(V8_OS_WIN64)
+#if defined(V8_TARGET_OS_WIN64)
if (win64_unwindinfo::CanEmitUnwindInfoForBuiltins()) {
EmitUnwindData(this, unwind_info_symbol, embedded_blob_data_symbol, blob,
reinterpret_cast<const win64_unwindinfo::BuiltinUnwindInfo*>(

View File

@@ -0,0 +1,45 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Sam Attard <sattard@anthropic.com>
Date: Wed, 8 Apr 2026 03:08:36 +0000
Subject: fix: use clang_x64_v8_arm64 snapshot toolchain for win-arm64 on
non-Windows hosts
snapshot_toolchain.gni special-cases is_win && v8_current_cpu == arm64
to use host_toolchain. is_win is true whenever the *target* is Windows,
but the special case only makes sense on a Windows host (where there is
no //build/toolchain/win:clang_x64_v8_arm64). On a Linux host,
host_toolchain is //build/toolchain/linux:clang_x64 which has
v8_current_cpu == x64, so mksnapshot is built with V8_TARGET_ARCH_X64
and emits an x64 builtins blob into the win-arm64 build.
Restrict the special case to host_os == win so non-Windows hosts fall
through to clang_x64_v8_arm64 (the arm64-simulator toolchain), matching
how every other linux->arm64 cross-compile works.
diff --git a/gni/snapshot_toolchain.gni b/gni/snapshot_toolchain.gni
index 37ed262640d048a6fa5923279ae0388c1c0ae766..c2d36dbcd5f84d9d5cf99266dca85b1f036fa215 100644
--- a/gni/snapshot_toolchain.gni
+++ b/gni/snapshot_toolchain.gni
@@ -83,9 +83,11 @@ if (v8_snapshot_toolchain == "") {
_cpus = v8_current_cpu
} else if (v8_current_cpu == "arm64" || v8_current_cpu == "mips64el" ||
v8_current_cpu == "riscv64" || v8_current_cpu == "loong64") {
- if (is_win && v8_current_cpu == "arm64") {
+ if (is_win && v8_current_cpu == "arm64" && host_os == "win") {
# set _cpus to blank for Windows ARM64 so host_toolchain could be
- # selected as snapshot toolchain later.
+ # selected as snapshot toolchain later. Only applies on a Windows
+ # host; a non-Windows host needs the clang_x64_v8_arm64 simulator
+ # toolchain so mksnapshot is built with V8_TARGET_ARCH_ARM64.
_cpus = ""
} else {
_cpus = "x64_v8_${v8_current_cpu}"
@@ -100,7 +102,7 @@ if (v8_snapshot_toolchain == "") {
if (_cpus != "") {
v8_snapshot_toolchain = "//build/toolchain/${host_os}:clang_${_cpus}"
- } else if (is_win && v8_current_cpu == "arm64") {
+ } else if (is_win && v8_current_cpu == "arm64" && host_os == "win") {
# cross compile Windows arm64 with host toolchain.
v8_snapshot_toolchain = host_toolchain
}

View File

@@ -0,0 +1,30 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Sam Attard <sattard@anthropic.com>
Date: Wed, 8 Apr 2026 03:39:01 +0000
Subject: fix: use %zu for size_t in arm64 EmitUnwindData SNPrintF
The arm64 EmitUnwindData path now compiles on Linux (-Wformat strict)
since the previous commit re-gated it on V8_TARGET_OS_WIN_ARM64.
diff --git a/src/snapshot/embedded/platform-embedded-file-writer-win.cc b/src/snapshot/embedded/platform-embedded-file-writer-win.cc
index b2319b9fea8b8ba8189ab577cbcf6982c3733bc0..6d3b3b3fe3e80d40ac71ce69682ea9a26f0d41d3 100644
--- a/src/snapshot/embedded/platform-embedded-file-writer-win.cc
+++ b/src/snapshot/embedded/platform-embedded-file-writer-win.cc
@@ -231,7 +231,7 @@ void EmitUnwindData(PlatformEmbeddedFileWriterWin* w,
// later.
code_chunks.push_back(allowed_chunk_len);
fp_adjustments.push_back(xdata_fp_adjustments[j]);
- base::SNPrintF(unwind_info_full_symbol, "%s_%u", unwind_info_symbol,
+ base::SNPrintF(unwind_info_full_symbol, "%s_%zu", unwind_info_symbol,
code_chunks.size());
w->DeclareRvaToSymbol(embedded_blob_data_symbol,
builtin_start_offset + chunk_start);
@@ -248,7 +248,7 @@ void EmitUnwindData(PlatformEmbeddedFileWriterWin* w,
w->StartXdataSection();
{
for (size_t i = 0; i < code_chunks.size(); i++) {
- base::SNPrintF(unwind_info_full_symbol, "%s_%u", unwind_info_symbol,
+ base::SNPrintF(unwind_info_full_symbol, "%s_%zu", unwind_info_symbol,
i + 1);
w->DeclareLabel(unwind_info_full_symbol.begin());
std::vector<uint8_t> xdata =

View File

@@ -59,7 +59,6 @@ const startServer = async () => {
function waitForCrash (): Promise<CrashInfo> {
return new Promise(resolve => {
emitter.once('crash', (crash) => {
console.log('crash fired', crash);
resolve(crash);
});
});
@@ -70,7 +69,6 @@ const startServer = async () => {
const fields = {} as Record<string, any>;
const files = {} as Record<string, Buffer>;
busboy.on('file', (fieldname, file) => {
console.log('Receiving file for :', fieldname);
const chunks = [] as Array<Buffer>;
file.on('data', (chunk) => {
chunks.push(chunk);
@@ -83,12 +81,10 @@ const startServer = async () => {
fields[fieldname] = val;
});
busboy.on('finish', () => {
console.log('On finish');
// breakpad id must be 16 hex digits.
const reportId = Math.random().toString(16).split('.')[1].padStart(16, '0');
res.end(reportId, async () => {
req.socket.destroy();
console.log('Emmitting crash:', fields);
emitter.emit('crash', { ...fields, ...files });
});
});
@@ -142,15 +138,10 @@ function waitForNewFileInDir (dir: string): Promise<string[]> {
ifdescribe(!isLinuxOnArm && !process.mas && !process.env.DISABLE_CRASH_REPORTER_TESTS)('crashReporter module', function () {
describe('should send minidump', () => {
it('when renderer crashes', async () => {
console.log('starting server for renderer crash test');
const { port, waitForCrash } = await startServer();
console.log('Done starting server for renderer crash test');
runCrashApp('renderer', port);
console.log('Waiting for renderer crash');
const crash = await waitForCrash();
console.log('Renderer crash received');
checkCrash('renderer', crash);
console.log('Renderer crash checked');
expect(crash.mainProcessSpecific).to.be.undefined();
});