Repository navigation
Conversation
…le on Windows x64 The Windows x64 static scan flags `_powf_special [AVX]` on some link layouts. MSVC stores the 9 RVAs of the function's switch table in .text after its `ret`, and the linear sweep decodes them as instructions. With the function at RVA 0x0519c200 the table entry `C4 C2 19 05` and the five bytes after it decode as VPHSUBW. Add `_powf_special` as a blanket pass to the data-in-.text group of allowlist-x64-windows.txt. The strspn family in that group has the same kind of table.
StatusReady for review and merge. The change is one allowlist entry and its comment. CI on this commit
How I reproduced the failure
With the allowlist of main, the scan fails with I could not download the artifact of build 126987 from my environment. The bytes in step 3 follow from the address in the CI log. The Notes block of the PR body shows how. |
There was a problem hiding this comment.
LGTM — a one-entry allowlist addition that follows the scanner's documented data-in-.text convention.
What was reviewed:
- The flagged bytes
C4 C2 19 05do decode as a VEX3 0F38-mapVPHSUBW(66-prefixed, opcode 05), consistent with a 4-byte RVA table entry rather than real code, and the 1-insn hit right afterretmatches the triage guide's false-positive signature. - Bare (blanket) entry is the sanctioned exception in scripts/verify-baseline-static/CLAUDE.md for confirmed misdecodes; it does not interact with the gated
powf [AVX, FMA]entry at line 957, which is a different symbol. - Group header count (4 symbols), ASCII sort order (
_befores), and comment placement match the existing strspn-family group; no scanner source or CI flags change.
Extended reasoning...
The change adds a single bare allowlist line plus an explanatory comment to scripts/verify-baseline-static/allowlist-x64-windows.txt, the CI-only static ISA scanner's Windows x64 suppression list; no runtime, build, or security-sensitive surface is touched. The byte sequence quoted in the PR decodes as claimed and the hit shape (one instruction, after the function's ret, inside a UCRT scalar-math helper) matches the repo's own triage guide for data-in-.text false positives, which explicitly prescribes a blanket pass. The only cost is that the scanner no longer bounds the 332-byte _powf_special body, the same trade-off already accepted for strspn/strcspn/strpbrk. The file is not covered by CODEOWNERS and the hunt ran dry with no findings.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
WalkthroughThe Windows x64 static-baseline allowlist now describes CRT inline switch tables as ChangesWindows x64 static baseline
Suggested reviewers: Priority: ⬇️ Low Merge Risk: ⚪ Minimal · up to
|
|
Updated 5:55 PM PT - Oct 18th, 2026
✅ @robobun, your commit c299f4a0f293ab8fbcf968e0b08d98e66f660664 passed in 🧪 To try this PR locally: bunx bun-pr 45886That installs a local version of the PR into your bun-45886 --bun |
… tables Each inline switch table of the four allowlisted CRT functions has an unnamed S_LDATA32 record at its first byte, inside the function's S_GPROC32. The group comment now says so, and that the scan does not read those records.
Problem
windows-x64-verify-baselinefails at one link layout: build 126987 on main (d7562f2, YAML.parse: name a key that is a sequence or a mapping once the input has been read #45593) and 18 pull request builds in 5 hours._powf_special(UCRT) ends with a 9-entry switch table in.text, and the scan decodes it as code. At0x14519c200the entryC4 C2 19 05starts aVPHSUBW. YAML.parse: name a key that is a sequence or a mapping once the input has been read #45593 only moved the layout.Fix
_powf_specialas a blanket pass to the data-in-.text group ofallowlist-x64-windows.txt, beside the strspn family.[AVX]ceiling is not enough: most flagged layouts decode another feature.bun-profile.exe. The scan fails as in CI on main's allowlist and passes on this one.Background
.textand fails on an instruction Nehalem cannot run, unless the allowlist names the symbol.S_LDATA32record. It is a separate change, and it deletes this group.Downsides
_powf_special.llint_entry [AVX]is not changed.Notes
Builds with this violation. 19 builds print it, all at
0x014519c364, created from 2026-10-16T21:52Z to 2026-10-17T02:36Z:impl Default for Property#45618), 127049 (node:stream: finish the decoder insetEncoding()when the stream has ended #45414), 127054 (bun check: fail the run on every reported diagnostic, not only categoryerror#45622), 127057 (fs.promises: FileHandle.writer() gives its ref back when a write rejects, and end()/fail() still run #45361), 127062 (bun patch --help: add --commit to the custom patches directory example #45417), 127067 (node:fs: store the Dirent entry type as an own Symbol(type) property #45425), 127070 (Remove dead code from bun_format and napi.cpp #45420), 127076 (js_parser: substitute undefined, not null, for top-levelthisin an ES module #32173), 127079 (worker_threads: do not install the Web Worker globals in a node worker #43600), 127095 (console: fill in a format specifier that directly follows%%#45626), 127096 and 127104 (install.sh: write ~/.bashrc first on Linux and skip files that already have the bun block #45418), 127107 (test: call noInline(hot) in the strict-mode hot loop fixture #45632), 127108 (test: do not assert that rss covers the ballast on macOS in harness-max-rss.test.ts #45633), 127109 (http: fail a tunnelled request with the error its callback found #44534), 127156 and 127177 (node:tls: reject a dhparam smaller than 1024 bits #45637).Main before it (126975, 0b2d346) and after it (127065, 4334326) passes the step. A retry does not help: the result is fixed for a given binary.
Why so many builds share one layout. The linker map has one chunk aligned to 256 bytes: the
.textof JavaScriptCore'sLowLevelInterpreter.cpp.obj(RVA0x042b5600in build 127915). It lies between Bun's own code and the CRT. A change to the code before it moves the CRT by a multiple of 256 bytes, or not at all. 127079 (#43600) and 127156, 127177 (#45637) branch from b28212a, two commits before #45593, and still link_powf_specialat the same address.The table.
_powf_specialcomes fromlibucrt.lib(pow_special.obj). All 23 direct calls to it are inpowf(the SSE2 path and the FMA3 path). In build 127915 (ed68082) it is at0x1451ce490:An RVA is an address relative to the image base. The table starts at
func+0x14c. Entry 6 is atfunc+0x164and holds the RVA offunc+0xc4.The failing layout. The flagged address
0x14519c364is entry 6, so the function was at0x14519c200and the entry held RVA0x0519c2c4. The sweep through that table:I could not download the
bun-windows-x64-profile.zipof build 126987 from my environment. The reproduction uses build 127915's artifact (the canary release asset) and the address from the CI log. The function is the same object in both: between the v1.4.3 release binary and build 127915, its code differs only in three relocated displacements, and the nine case offsets are equal.Scanner runs (
scripts/verify-baseline-static/CLAUDE.mdsteps, scanner built from this repository):_powf_special [AVX] (1 insns),Vphsubw (AVX)_powf_specialis in the allowlisted group0x42d99fc)_powf_specialis a stale entry_powf_specialis a stale entryA stale entry is not an error.
strcspn,strpbrkandstrspnare stale in the same runs. In the CI runs of this PR (builds 128150 and 128539) the step passes with 0 violations.How many functions have such a table. Two searches over
.text, each run on build 127915 and on the v1.4.3 release, find the same four functions:strcspn,strspnandstrpbrkwith three tables each, and_powf_specialwith one.mov r32, [base + index*4 + disp32]whosedisp32is an RVA inside the same function.The pinned
libucrt.lib(10.0.26100.8249,scripts/build/winsysroot.ts) has 15 functions with such tables in 7 objects. The 11 that are not linked today are_pow_special, eight functions offilter_simd.obj,_XMMI_FP_Emulationand_XMMI2_FP_Emulation.The PDB marks the tables. Each of the ten tables has an unnamed
S_LDATA32record with no type at its first byte, inside the function'sS_GPROC32.llvm-pdbutil dump -symbols -modi=866 bun-profile.pdbshows_powf_specialwith code size 368 and the record at+0x14c.strcspnandstrspnhave records at+0x314,+0x350,+0x390, andstrpbrkat+0x2fc,+0x338,+0x378.scan_aarch64already skips data that the toolchain marks.scan_x86_64takes no such ranges. A scan that skips these records makes the whole group unnecessary and checks the code of the four functions again. It must skip only 4-byte words that are RVAs into the function, not everything up to the function's end.Layouts that flag each function. Each function was decoded with the scanner's own filters at every 16-byte-aligned RVA in
0x05000000..0x06000000(1,048,576 positions):_powf_specialstrcspnstrspnstrpbrkThe 0.35% is a mean over two regimes:
0x05C50000..0x05C60000, 3,022 of 4,096 positions flag_powf_special(74%). Each entry then ends inC5 05, andC5is a VEX prefix. With the function at RVA0x05C51230the table decodes asVpmuludqandVpunpckhqdq(AVX2), so an[AVX]ceiling fails there.strcspn,strspnandstrpbrkeach flag 4,072 of 4,096 positions in this band.The band starts 10.5 MiB above the position of
_powf_specialin build 127915.Not in this change.
llint_entry [AVX], the other data-in-.text group of this file. On Windows the interpreter is one symbol, so the decoder's restart at symbol starts does not help inside it.Self-review. A review of this change raised 8 concerns. This push addresses 7: the build count, the cause, the rate and the scope in this description, and the PDB records in the description and in the group comment. The review also asked for a tracking issue for the scanner change. I did not file one.
Related. #40672 (open) lists the same tables in its notes. It does not add this entry.
no test proof · iteration 0 · build/CI scripts only; test-proof not applicable