Skip to content

win32: add missing intrin.h/dbghelp.h headers so tcc can build vc/v_win.c (i386) - #98

Merged
medvednikov merged 2 commits into
vlang:thirdparty-windows-i386from
quaesitor-scientiam:fix-windows-intrin-dbghelp-headers-i386
Sep 30, 2026
Merged

medvednikov merged 2 commits into
vlang:thirdparty-windows-i386from
quaesitor-scientiam:fix-windows-intrin-dbghelp-headers-i386

Conversation

@quaesitor-scientiam

@quaesitor-scientiam quaesitor-scientiam commented Sep 28, 2026 •

Copy link
Copy Markdown

Summary

Why this is needed here too

Verified before porting rather than assumed: thirdparty-windows-i386's include/_mingw.h predefines __INTRIN_H_ at line 140 - the exact same guard on thirdparty-windows-amd64 (line 146) that made a naive port of the real intrin.h a silent no-op in #96 (its body gets skipped unless this macro is absent). Neither include/intrin.h nor include/dbghelp.h existed on this branch beforehand, matching amd64's pre-#96 state exactly.

This path is real, but has no CI coverage anywhere

Checked before assuming - thirdparty-windows-i386 is not dead code:

  • vlang/v's makev.bat has a documented -tcc32 flag that forces this branch, and it's also the automatic default on a 32-bit Windows host (PROCESSOR_ARCHITECTURE == x86). There's a dedicated :tcc32_strap bootstrap routine parallel to the amd64 one.
  • However, no vlang/v GitHub Actions workflow exercises -tcc32 or a 32-bit host, and vlang/tccbin itself has no .github/workflows directory at all - nothing in CI validates any branch here, i386 or amd64.

So this fixes a real gap on a genuinely reachable code path, but neither this fix nor the original bug it mirrors would ever be caught by CI. That raises the stakes on the test-plan gap below rather than lowering them.

Test plan

  • Confirmed the ported files are byte-identical to win32: add missing intrin.h/dbghelp.h headers so tcc can build vc/v_win.c #96's fix (git diff shows the same 2320 insertions across the same 6 files).
  • Not independently build-verified against a 32-bit tcc.exe + vc/v_win.c in this session (no i386 TCC toolchain or i386 V build target available here, unlike the amd64 fix which was verified with a real forced-MSVC/TCC build). Flagging this gap explicitly rather than claiming parity I haven't tested.

🧙 Built with WOZCODE

…in.c (i386)

Mirrors the fix applied to thirdparty-windows-amd64 in vlang#96. The
32-bit branch's _mingw.h predefines __INTRIN_H_ at line 140, the same
guard that silently skipped a ported real intrin.h's body on amd64 -
confirmed before porting these files rather than assumed. Neither
intrin.h nor dbghelp.h existed on this branch prior to this commit,
identical to amd64's pre-vlang#96 state.

Co-Authored-By: WOZCODE <contact@withwoz.com>
Per an adversarial review of vlang#98 (2 findings, each confirmed by all
3 independent lenses):

- intrin.h cited "_mingw.h line ~146" for the __INTRIN_H_ guard, but
  that's the amd64 branch's line, carried over unedited from vlang#96.
  This branch's own line is 140. Dropped the specific number entirely
  (it will drift again the next time either branch's _mingw.h
  changes) in favor of pointing at the macro name to grep for.

- dbghelp.h claimed the windows.h -> intrin.h -> dbghelp.h include
  order "has been verified to build" - true on the amd64 sibling
  (a real forced-MSVC/TCC build was run for vlang#96), not true here: no
  i386 TCC toolchain or V build target was available to verify this
  branch, as vlang#98's own description already discloses. The claim as
  shipped would outlive that disclosure once the PR closes, so a
  future reader of just this file would take it as settled fact.
  Removed the claim and pointed at vlang#98 for the real status instead.

Co-Authored-By: WOZCODE <contact@withwoz.com>
@quaesitor-scientiam

Copy link
Copy Markdown
Author

Ran an adversarial review pass on this PR (3 lenses: doc-accuracy, sibling-parity, arch-correctness; 3 adversarial refuters per candidate). 6 raw candidates, all confirmed, collapsing into 2 distinct real issues (the rest were repeat findings of the same two from different lenses):

  1. intrin.h cited the wrong _mingw.h line number for the __INTRIN_H_ guard. Said "see its line ~146" - that's the amd64 branch's line, carried over unedited from win32: add missing intrin.h/dbghelp.h headers so tcc can build vc/v_win.c #96. This branch's own line is 140. Fixed by dropping the specific line number entirely rather than just correcting the digit, since it would drift again on the next edit to either branch's _mingw.h.

  2. dbghelp.h claimed the include order "has been verified to build." True on the amd64 sibling (a real forced-MSVC/TCC build was run for win32: add missing intrin.h/dbghelp.h headers so tcc can build vc/v_win.c #96) - not true here, since no i386 TCC toolchain or V build target was available to verify this branch, as this PR's own description already discloses. The distinction the review surfaced: that disclosure lives in the PR description, which outlives nothing once the PR closes, while the false claim would have persisted permanently in the shipped header. Removed the claim.

Both fixed in 2893cc1 - comment-only changes, no #ifndef/#define/#include lines touched.

No correctness/build-behavior findings survived review - the architecture-correctness lens specifically checked the _IMAGEHLP64/_WIN64 conditional and the ported struct/type usage for 32-bit-vs-64-bit issues and found nothing beyond the two comment inaccuracies above.

@medvednikov medvednikov left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the i386 port at 2893cc17d3c30904f509486ace121b3d197473b4, comparing its added headers with #96 and checking relevant definitions in this branch's own _mingw.h, _mingw_unicode.h, and winapi/winnt.h. CI status/results were not considered.

No actionable correctness issue found in the header integration reviewed. A real i386 TinyCC/bootstrap build remains unverified.

The empty intrin.h shim has an independent guard and no missing include dependencies. The latest comment-only changes avoid both the amd64-specific line-number claim and any assertion that this branch has been build-tested.

The DbgHelp wrapper defines _IMAGEHLP64 only under _WIN64; it does not accidentally force the native 32-bit aliases to their 64-bit counterparts. The explicit 64-bit DbgHelp interfaces remain declared alongside the 32-bit variants, as intended. IMAGEAPI retains the branch's WINAPI/stdcall convention. I checked the extra dependencies of the non-_WIN64 IMAGE_DEBUG_INFORMATION declaration: the bundled winnt.h supplies PIMAGE_FUNCTION_ENTRY, PFPO_DATA, and PIMAGE_COFF_SYMBOLS_HEADER. _mingw_unicode.h is also present. The _dbg_common.h blob matches both #96 and upstream mingw-w64 exactly (aa94da4a79260cc06e801c37d6343a3efbda5a48).

The push/pop packing helpers deliberately have no once-only include guard, so repeated pairing restores the caller's packing state. The documented requirement to include <windows.h> before <dbghelp.h> still applies.

Validation: source inspection plus isolated Clang syntax/layout probes of the shim and packing helpers' active contents for both Windows pointer widths. All 12 configurations passed, including an already-defined __INTRIN_H_, repeated inclusion, nested packing restoration, and RC_INVOKED/lint bypasses (-Wno-pragma-pack suppresses the expected cross-header packing-change warning). These are not full DbgHelp/bundled-header compilation or ABI-runtime tests.

Before treating this port as empirically build-verified, the useful remaining check is a real i386 tcc.exe -c smoke test using <windows.h>, <intrin.h>, and <dbghelp.h>, followed by the intended V bootstrap. I did not run either: this environment lacks Windows execution and a V compiler, and direct checkout downloads fail DNS resolution. I am not inferring a passing i386 build from the amd64 report.

@quaesitor-scientiam

Copy link
Copy Markdown
Author

Did exactly the check you suggested: extracted the real i386 tcc.exe from this branch (with its libtcc.dll and lib/libgc-1.dll dependencies colocated - without them it fails to launch at all with a misleading STATUS_INVALID_IMAGE_FORMAT, not a missing-header error), and ran it against the actual vc/v_win.c using makev.bat's exact build_bootstrap_with_tcc flags, with this PR's headers plus the branch's existing include tree.

Result: it gets further than before, but doesn't fully succeed, for two reasons neither of which is in this PR's headers:

  1. include/winapi/psapi.h doesn't exist anywhere on this branch (it's a pre-existing part of amd64's base bundle, not something win32: add missing intrin.h/dbghelp.h headers so tcc can build vc/v_win.c #96 or win32: add missing intrin.h/dbghelp.h headers so tcc can build vc/v_win.c (i386) #98 added) - v_win.c's #include <psapi.h> fails without it. Opened win32: add missing include/winapi/psapi.h (i386) #100 to add it (ported and confirmed via the same real i386 tcc.exe that it clears this specific error and the build progresses further).

  2. Past that, it fails at v_win.c:682 (typedef _Atomic bool atomic_bool;) with ';' expected (got "_Bool"). This branch's tcc.exe is version 0.9.27 (stock, 2017) vs. amd64's 0.9.28rc (a newer custom fork, dated 2026-07-14) - the old binary doesn't support the C11 _Bool/_Atomic syntax the current v_win.c snapshot uses. The exact same file, same flags, compiles clean (exit 0) against the real amd64 tcc.exe. Opened thirdparty-windows-i386's tcc.exe is a much older build than amd64's, and cannot compile the current vc/v_win.c #99 for this, since it's a toolchain-provenance/rebuild question, not something fixable at the header level.

So: this PR's own content is fine (confirmed by both the adversarial review and by real compilation getting past the exact code path it touches), but a full i386 bootstrap needs #100 and, more substantially, whatever #99 resolves to.

JalonSolov pushed a commit that referenced this pull request Sep 29, 2026
Ported from thirdparty-windows-amd64, where this file is a
pre-existing part of the base bundle (not something #96/#98 added).
It does not exist anywhere on thirdparty-windows-i386.

Confirmed via a real build: without this file, compiling vc/v_win.c
with this branch's tcc.exe fails at v_win.c:58 on
#include <psapi.h>. With it added, the build gets substantially
further (to v_win.c:682, an unrelated _Bool/_Atomic feature gap in
this branch's older 0.9.27 tcc.exe vs. amd64's 0.9.28rc build - see
#99, which this PR does not attempt to fix).

The ported file's one arch-sensitive spot (PSAPI_WORKING_SET_BLOCK's
VirtualPage bitfield width) already branches correctly on _WIN64,
which is unset for this branch's i386 target.

Co-Authored-By: WOZCODE <contact@withwoz.com>

Copy link
Copy Markdown
Member

Follow-up at 2893cc17d3c30904f509486ace121b3d197473b4, after the new i386 build report. CI status/results were not considered.

The head is unchanged from my previous review, which found no actionable correctness issue in this header port. There is no new source fix to re-review, and I am not requesting another code change to these six files based on this follow-up.

Thanks for attempting the real i386 bootstrap. The report usefully separates the missing psapi.h (#100) and the compiler/bootstrapping work (#99) from this PR. Those separately tracked failures should not be presented as defects established in the intrin.h/DbgHelp additions.

One validation distinction remains: the reported run stops at an error in vc/v_win.c; it is not a successful end-to-end bootstrap or a recorded passing standalone header smoke test. Progressing to that error alone does not demonstrate that every added header has been parsed successfully. To isolate this PR from the bootstrap's other failures, the useful check is tcc.exe -c on a small translation unit containing, in order, <windows.h>, <intrin.h>, and <dbghelp.h>, using this branch's bundled include tree. An exit-zero result there would establish include/parse compatibility independently of #99; DbgHelp linking/runtime compatibility would still be a separate check.

This follow-up verifies the unchanged head and assesses the new report; it does not claim a new full source review or independent execution of the author's test. I did not run Windows TCC, the standalone smoke test, or a V bootstrap in this pass. The previous source-review conclusion stands; complete i386 bootstrap success is not established by this update.

@quaesitor-scientiam

Copy link
Copy Markdown
Author

Ran the standalone -c smoke test suggested in the review, and checked one more thing that affects whether the i386 branch needs these headers at all.

Setup

Results

tree + compiler control with the PR's headers
i386 branch, 2020 snapshot intrin.h not found exit 0
i386 branch, mainline intrin.h not found exit 0
amd64 branch, d9d02c56 + patches intrin.h not found exit 0

A second file that also calls SymInitialize, SymFromAddr, SymGetLineFromAddr64 and StackWalk64, and uses SYMBOL_INFO, IMAGEHLP_LINE64 and STACKFRAME64, also compiles clean in all three.

So the headers in this PR are fine for the i386 branch, and #96's headers already work for a 32-bit target through the amd64 bundle's cross compiler.

vc/v_win.c
Compiling current vc/v_win.c (the file makev.bat -tcc32 builds) with the i386 trees:

  • The 2020 snapshot stops at line 683 (_Atomic bool), before the <intrin.h>/<dbghelp.h> includes at lines 1169-1170, so that failure never exercises this PR's headers. _Atomic support landed in tcc in January 2021, after this snapshot.
  • Mainline gets through both includes, then stops at line 1395: #error "this C was generated by v -os cross for a 64-bit target; regenerate it for this one".

The guard is deliberate: CI generates v_win.c on 64-bit Linux and there is no 32-bit variant, so a native i386 bootstrap from it is blocked independently of this PR, and a newer tcc alone would not fix it. I used current vc master, so line numbers may differ from the snapshot used earlier.

Question for maintainers
Given the above, is thirdparty-windows-i386 still needed as a native host branch? The 32-bit support V uses (tcc -m32, as in create_win_dll_test.v) defers to i386-win32-tcc.exe, which the amd64 bundle already ships at the same tcc version as its tcc.exe. If the i386 branch were frozen or retired, this PR and #99 would be moot, and one tcc version would cover both targets. I can draft that change if wanted. Two things to settle first: the amd64 bundle has only a 64-bit libgc.a, so a -m32 program using the GC would need an i386 build (I did not check what the test does about that), and makev.bat/contract.v still reference the i386 branch.

Not covered: linking or running anything that uses DbgHelp, running any Windows binary (all checks were header parses with Linux-hosted cross builds of the same sources), and the shipped tcc.exe itself.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants