Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 12 additions & 6 deletions .github/verify/artifacts/wee8.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@
set -euo pipefail

ARTIFACT_DIR="${1:?usage: wee8.sh <artifact-dir>}"
CHECK_STDLIB="$(dirname "$0")/../../../bazel/compile/test/check_stdlib.sh"
CHECK_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../bazel/compile/test" && pwd)"
CHECK_STDLIB="${CHECK_DIR}/check_stdlib.sh"
CHECK_GLIBC="${CHECK_DIR}/check_glibc.sh"

# Keep in sync with WEE8_VARIANTS in bazel/v8/package/BUILD. aarch64+libstdcxx
# is deliberately absent: the gcc toolchain invokes /usr/bin/gcc directly and
# has no cross-compiler, so that combination cannot be built.
EXPECTED_COUNT=3
# Keep in sync with WEE8_VARIANTS in bazel/v8/package/BUILD.
EXPECTED_COUNT=4

if [[ ! -d "${ARTIFACT_DIR}" ]]; then
echo "FAIL: artifact dir '${ARTIFACT_DIR}' does not exist"
Expand All @@ -37,7 +37,9 @@ fi

shopt -s nullglob globstar

WORKDIR="$(mktemp -d)"
ARTIFACT_DIR="$(cd "${ARTIFACT_DIR}" && pwd)"
WORKDIR="${ARTIFACT_DIR}/.wee8-verify-$$"
mkdir "${WORKDIR}"
trap 'rm -rf "${WORKDIR}"' EXIT

found=0
Expand Down Expand Up @@ -101,6 +103,10 @@ for tarball in "${ARTIFACT_DIR}"/**/v8-wee8-*.tar.xz; do
rc=1
fi

if ! BINARY="${lib}" bash "${CHECK_GLIBC}"; then
rc=1
fi

rm -rf "${objdir}" "${lib}"
done

Expand Down
15 changes: 2 additions & 13 deletions .github/workflows/_release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,6 @@ on:
fi
done
OUTPUT=$(printf '%s\n' "${_OUTPUT[@]}")
stdcc-versions:
type: string
default: |
["base", "13"]
template-version-update:
type: string
default: |
Expand Down Expand Up @@ -197,7 +193,6 @@ jobs:
current: ${{ steps.bins-deps.outputs.output }}
shas: ${{ steps.bins-shas.outputs.shas }}
glibc_versions: ${{ inputs.glibc-versions }}
stdcc_versions: ${{ inputs.stdcc-versions }}
arches: ${{ inputs.arches }}
glint_version: ${{ inputs.glint-version }}
versions_file: ${{ inputs.bazel-versions-file }}
Expand All @@ -212,7 +207,6 @@ jobs:
| .current as $current
| .glibc_versions as $glibc_versions
| .arches as $arches
| .stdcc_versions as $stdccs
| .san as $san
| .glint_version as $glint_version
| .versions_file as $versions_file
Expand Down Expand Up @@ -250,16 +244,11 @@ jobs:
else "" end] as $glint_updates
| [$glibc_versions[]
| . as $glibc
| $stdccs[]
| . as $stdcc
| (if $stdcc == "base" then ""
else "-libstdc++\($stdcc)"
end) as $stdcc_extra
| "sysroot-glibc\($glibc)\($stdcc_extra)-\($arch).tar.xz" as $sysroot
| "sysroot-glibc\($glibc)-\($arch).tar.xz" as $sysroot
| ($shas[$sysroot]
| split(":")
| .[1]) as $new_sha
| $current.sysroot_hashes[$glibc][$stdcc][$arch] as $current_sha
| $current.sysroot_hashes[$glibc][$arch] as $current_sha
| if $current_sha != $new_sha then
"sed -i s/\($current_sha)/\($new_sha)/g \($versions_file)"
else "" end] as $sysroot_updates
Expand Down
18 changes: 16 additions & 2 deletions .github/workflows/bazel.yml
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,8 @@ jobs:
verify-artifacts:
# Asserts that uploaded artifacts actually contain what their filenames
# claim. The build succeeding is not evidence of this: toolchain
# resolution can silently fall back to LLVM, and a gcc "cross" toolchain
# with no cross-compiler emits host-arch objects under a target-arch name.
# resolution can silently fall back to LLVM, and a misconfigured cross
# toolchain can emit host-arch objects under a target-arch name.
# Both produce a green build and a plausible-looking tarball.
#
# Wee8, darwin libcxx, and macOS sysroot are verified below.
Expand Down Expand Up @@ -209,6 +209,20 @@ jobs:
@envoy_toolshed_jq//...
//sysroot:sysroots
//compile/test:libunwind_shared_test
- name: gcc
action: test
bazel_args: >-
--config=ci
--config=gcc
privileged: false
rbe: true
runner: ubuntu-24.04
targets: >-
//compile/test:check_glibc_test
//compile/test:stdlib_libstdcxx_test
//compile/test:gcc_runtime_test
//toolchains/gcc:linux_x64_paths_test
//toolchains/gcc:linux_arm64_paths_test
- name: x86-to-arm
action: test
bazel_args: >-
Expand Down
29 changes: 24 additions & 5 deletions bazel/MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ use_repo(macos_sysroot_build_ext, "macos_sdk_pkg", "pkgutil_linux_amd64")
# stays a dev dependency.
wee8_prebuilt_ext = use_extension("//v8:extensions.bzl", "wee8_prebuilt_extension")
wee8_prebuilt_ext.setup()
use_repo(wee8_prebuilt_ext, "wee8_prebuilt_aarch64", "wee8_prebuilt_x86_64", "wee8_prebuilt_x86_64_libstdcxx", "wee8_source")
use_repo(wee8_prebuilt_ext, "wee8_prebuilt_aarch64", "wee8_prebuilt_aarch64_libstdcxx", "wee8_prebuilt_x86_64", "wee8_prebuilt_x86_64_libstdcxx", "wee8_source")

wee8_source_ext = use_extension("//v8:extensions.bzl", "wee8_prebuilt_extension", dev_dependency = True)
wee8_source_ext.setup(source = "@v8//:wee8")
Expand Down Expand Up @@ -168,7 +168,20 @@ use_repo(grcov_ext, "grcov")
# glint_ext.setup(bins_release_version = "0.1.21")
# use_repo(glint_ext, "glint")

# This needs to be before llvm to win in transitionsj
gcc = use_extension("//toolchains/gcc:extensions.bzl", "gcc_extension", dev_dependency = True)
gcc.toolchain(
name = "gcc_linux_x86_64",
arch = "x86_64",
sysroot = "@sysroot_linux_amd64//sysroot",
)
gcc.toolchain(
name = "gcc_linux_aarch64",
arch = "aarch64",
sysroot = "@sysroot_linux_arm64//sysroot",
)
use_repo(gcc, "gcc_linux_aarch64", "gcc_linux_x86_64")

# This needs to be before llvm to win in transitions.
register_toolchains(
"//toolchains/gcc:linux_x64_toolchain",
"//toolchains/gcc:linux_arm64_toolchain",
Expand All @@ -195,11 +208,17 @@ llvm.cxx_cross_lib(
# libgcc_s NEEDED entry.
llvm.toolchain(
name = "llvm_toolchain",
llvm_version = "22.1.8",
extra_link_flags = {
"linux-aarch64": ["-rtlib=compiler-rt", "-unwindlib=libgcc"],
"linux-x86_64": ["-rtlib=compiler-rt", "-unwindlib=libgcc"],
"linux-aarch64": [
"-rtlib=compiler-rt",
"-unwindlib=libgcc",
],
"linux-x86_64": [
"-rtlib=compiler-rt",
"-unwindlib=libgcc",
],
},
llvm_version = "22.1.8",
)
llvm.toolchain_root(
name = "llvm_toolchain",
Expand Down
48 changes: 44 additions & 4 deletions bazel/compile/test/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,16 @@ clang_version_test(
name = "clang_version_test",
)

sh_test(
name = "check_glibc_test",
size = "small",
srcs = ["check_glibc_test.sh"],
data = [
"check_glibc.sh",
"glibc_tool_fixture.sh",
],
)

sh_test(
name = "libunwind_shared_test",
size = "small",
Expand Down Expand Up @@ -246,19 +256,22 @@ cc_binary(
#
# Note these are gated the *inverse* way from the unwind tests above: the
# libstdcxx variant only runs when :gcc_build is set, and vice versa. Every
# other binary-inspecting test in this package is disabled under gcc, which is
# why the gcc leg had no output verification at all.
# other unwind-inspecting test in this package is disabled under gcc.
#
# Run with:
# bazel test //compile/test:stdlib_libstdcxx_test --config=gcc
sh_test(
name = "stdlib_libstdcxx_test",
size = "small",
srcs = ["check_stdlib.sh"],
data = [":test_stdlib"],
data = [
":test_stdlib",
"@llvm_toolchain_llvm//:nm",
],
env = {
"BINARY": "$(rootpath :test_stdlib)",
"EXPECTED_STDLIB": "libstdcxx",
"NM": "$(rootpath @llvm_toolchain_llvm//:nm)",
},
tags = ["manual"],
target_compatible_with = select({
Expand All @@ -273,10 +286,14 @@ sh_test(
name = "stdlib_libcxx_test",
size = "small",
srcs = ["check_stdlib.sh"],
data = [":test_stdlib"],
data = [
":test_stdlib",
"@llvm_toolchain_llvm//:nm",
],
env = {
"BINARY": "$(rootpath :test_stdlib)",
"EXPECTED_STDLIB": "libcxx",
"NM": "$(rootpath @llvm_toolchain_llvm//:nm)",
},
tags = ["manual"],
target_compatible_with = select({
Expand All @@ -285,3 +302,26 @@ sh_test(
"//conditions:default": [],
}),
)

# Inspect the linked binary without executing it, including on cross builds.
sh_test(
name = "gcc_runtime_test",
size = "small",
srcs = ["check_glibc.sh"],
data = [
":test_stdlib",
"@llvm_toolchain_llvm//:nm",
"@llvm_toolchain_llvm//:readelf",
],
env = {
"BINARY": "$(rootpath :test_stdlib)",
"CHECK_STATIC_RUNTIME": "true",
"NM": "$(rootpath @llvm_toolchain_llvm//:nm)",
"READELF": "$(rootpath @llvm_toolchain_llvm//:readelf)",
},
tags = ["manual"],
target_compatible_with = select({
"//compile:gcc_build": [],
"//conditions:default": ["@platforms//:incompatible"],
}),
)
54 changes: 54 additions & 0 deletions bazel/compile/test/check_glibc.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#!/bin/bash
# Inspect every archive member (or a linked ELF binary) for glibc > 2.31.
# Unversioned newer entry points must also be rejected in relocatable objects.
set -euo pipefail

: "${BINARY:?BINARY must be set}"
NM="${NM:-nm}"
READELF="${READELF:-readelf}"

# Capture complete output before matching: grep -q pipelines can SIGPIPE nm,
# and inspecting only one archive member misses incompatible references.
undefined="$("${NM}" -u "${BINARY}")"
if grep -E '(^|[[:space:]])(__isoc23_[^[:space:]@]*|__libc_single_threaded)(@[^[:space:]]*)?([[:space:]]|$)' <<< "${undefined}"; then
echo "FAIL: ${BINARY} references glibc entry points newer than 2.31"
exit 1
fi

versions="$("${READELF}" --version-info "${BINARY}")"
if ! awk '
{
line = $0
while (match(line, /GLIBC_[0-9]+(\.[0-9]+)+/)) {
version = substr(line, RSTART + 6, RLENGTH - 6)
count = split(version, parts, ".")
# Compare numeric components, not strings (2.9 < 2.31 < 2.100).
for (i = 1; i <= count; i++) {
limit = (i == 1 ? 2 : (i == 2 ? 31 : 0))
if (parts[i] + 0 > limit) {
print "FAIL: GLIBC_" version " exceeds GLIBC_2.31"
failed = 1
break
}
if (parts[i] + 0 < limit) {
break
}
}
line = substr(line, RSTART + RLENGTH)
}
}
END { exit failed }
' <<< "${undefined}
${versions}"; then
exit 1
fi
echo "PASS: ${BINARY} requires no glibc newer than 2.31"

if [[ "${CHECK_STATIC_RUNTIME:-false}" == "true" ]]; then
dynamic="$("${READELF}" -d "${BINARY}")"
if grep -E '\(NEEDED\).*(libstdc\+\+|libgcc_s)' <<< "${dynamic}"; then
echo "FAIL: ${BINARY} dynamically links the GCC C++ runtime"
exit 1
fi
echo "PASS: no dynamic libstdc++ or libgcc_s dependencies"
fi
46 changes: 46 additions & 0 deletions bazel/compile/test/check_glibc_test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#!/bin/bash
set -euo pipefail
cd "$(dirname "${BASH_SOURCE[0]}")"
export BINARY=fixture.a
export NM="${PWD}/glibc_tool_fixture.sh"
export READELF="${NM}"
export CHECK_STATIC_RUNTIME=true

assert_check() {
local expected="$1"
shift
local output status=0
output="$(env "$@" bash ./check_glibc.sh 2>&1)" || status=$?
if [[ "${expected}" == "pass" && "${status}" -ne 0 ]] ||
[[ "${expected}" == "fail" && "${status}" -eq 0 ]]; then
printf 'FAIL: expected %s for %s\n%s\n' "${expected}" "$*" "${output}"
exit 1
fi
echo "PASS: expected ${expected} for $*"
}

assert_check pass
assert_check pass FIXTURE_UNDEFINED='U memcpy@GLIBC_2.9'
assert_check pass FIXTURE_UNDEFINED='U memcpy@GLIBC_2.31.0'
assert_check pass FIXTURE_UNDEFINED='U memcpy@GLIBC_2.3.4'
assert_check pass FIXTURE_UNDEFINED='U ordinary_symbol'
assert_check pass FIXTURE_UNDEFINED='U prefixed__isoc23_strtol'
assert_check pass FIXTURE_UNDEFINED='U prefixed__libc_single_threaded'
assert_check pass FIXTURE_VERSIONS='Name: GLIBCXX_3.4.32 Name: GLIBC_2.31'
assert_check fail FIXTURE_UNDEFINED='U memcpy@GLIBC_2.32'
assert_check fail FIXTURE_UNDEFINED='U memcpy@GLIBC_2.100'
assert_check fail FIXTURE_UNDEFINED='U memcpy@GLIBC_2.31.1'
assert_check fail FIXTURE_UNDEFINED='U memcpy@GLIBC_3.0'
assert_check fail FIXTURE_VERSIONS='Name: GLIBC_2.9 Name: GLIBC_2.34'
assert_check fail FIXTURE_UNDEFINED='U __isoc23_strtol'
assert_check fail FIXTURE_UNDEFINED='U __isoc23_sscanf@GLIBC_2.38'
assert_check fail FIXTURE_UNDEFINED='U __libc_single_threaded'
assert_check fail FIXTURE_UNDEFINED='w __libc_single_threaded@GLIBC_2.32'
assert_check fail FIXTURE_UNDEFINED='U __libc_single_threaded@@GLIBC_2.32'
assert_check fail FIXTURE_LARGE=true FIXTURE_UNDEFINED='U __isoc23_strtoul'
assert_check pass FIXTURE_LARGE=true
assert_check fail FIXTURE_DYNAMIC='0x00000001 (NEEDED) Shared library: [libstdc++.so.6]'
assert_check fail FIXTURE_DYNAMIC='0x00000001 (NEEDED) Shared library: [libgcc_s.so.1]'
assert_check pass FIXTURE_DYNAMIC='0x00000001 (NEEDED) Shared library: [libc.so.6]'
assert_check fail FIXTURE_NM_FAIL=true
assert_check fail FIXTURE_READELF_FAIL=true
24 changes: 24 additions & 0 deletions bazel/compile/test/glibc_tool_fixture.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/bin/bash
# Deliberately accept only the arguments used by the checker.
set -euo pipefail
[[ "$#" -eq 2 && "$2" == "fixture.a" ]] || exit 90
case "$1" in
-u)
[[ "${FIXTURE_NM_FAIL:-false}" != "true" ]] || exit 91
printf 'first.o:\n U memcpy\n'
if [[ "${FIXTURE_LARGE:-false}" == "true" ]]; then
for ((i = 0; i < 5000; i++)); do
printf ' U harmless_symbol_%s\n' "${i}"
done
fi
printf 'last.o:\n %s\n' "${FIXTURE_UNDEFINED:-U memcpy@GLIBC_2.31}"
;;
--version-info)
[[ "${FIXTURE_READELF_FAIL:-false}" != "true" ]] || exit 92
printf '%s\n' "${FIXTURE_VERSIONS:-No version information found.}"
;;
-d)
printf '%s\n' "${FIXTURE_DYNAMIC:-There is no dynamic section in this file.}"
;;
*) exit 93 ;;
esac
Loading
Loading