Skip to content

feat(extract): make cgo visible — //export contracts, C. veto, preamble coverage - #1947

Draft
ilyabrykau-orca wants to merge 1 commit into
DeusData:mainfrom
ilyabrykau-orca:fix/go-cgo-export-linkage
Draft

feat(extract): make cgo visible — //export contracts, C. veto, preamble coverage#1947
ilyabrykau-orca wants to merge 1 commit into
DeusData:mainfrom
ilyabrykau-orca:fix/go-cgo-export-linkage

Conversation

@ilyabrykau-orca

Copy link
Copy Markdown

Part of #1929draft implementation-proposal: implements the three bounded pieces sketched in the issue body; the design-sized fourth (parsing the C preamble with a second grammar) deliberately stays open for maintainer design. Will mark ready on ack.

1. //export linkage — a declared contract, not short-name luck

cgo requires the exported name to equal the func name, yet C-side callers bound Go //export functions via unique_name at 0.38–0.75 — right by accident, and one name collision away from moving silently or dying in a weak-match guard. Now: the Go extractor records the directive (CBMDefinition.is_cgo_export, node property "cgo_export":true), and both CALLS resolvers upgrade an exact-name C/C++ caller to export_linkage @ 0.95. 22 luck-based edges on the measured repo become declared contracts.

2. C. pseudo-namespace veto

"C" is reserved by go/build — no project symbol can be behind C.<ident>, so any binding the general resolver produces is fabricated (a standing #1906-shaped hijack surface; pairs with #1931's import "C" drop). New pure predicate cbm_go_suppress_cgo_callee vetoes such callees in both resolvers before any strategy can bind them.

3. Preamble coverage honesty

A cgo file parses CLEAN — the preamble is a comment to the Go grammar — so parse_partial claimed full indexing while every preamble definition (12 C functions in one measured file) was missing. The comment run directly above import "C" is now flagged as an unparsed region (parse_incomplete + error_ranges), the same best-effort detection signal as #963. This intentionally makes every cgo file report a partial-parse range — that is the point; if maintainers prefer a distinct marker key for "foreign-language region" vs "parse error", happy to split it.

Tests (reproduce-first — RED with the wiring stashed, GREEN restored)

  • extract_go_cgo_export_flag: exact-name gate (mismatched directive and plain funcs stay false), preamble range 3-5 flagged, cgo-without-preamble and plain Go stay clean.
  • pipeline_go_cgo_export_binds_by_contract: RED — edge exists as unique_name; GREEN — carries export_linkage.
  • pipeline_go_cgo_callee_never_binds_project_symbol: C.helper() + a project helper decoy → zero edges (RED bound the decoy).
  • go_cgo_callee_veto predicate units. 784 green across extraction/pipeline/registry/lsp probes/go_lsp; full scripts/test.sh venue leg green; clang-format clean.

Field census

Pending (live-daemon rendezvous conflict blocks isolated-HOME one-shots on this machine); expected per the issue: 22 //export inbound edges move from unique_name@0.38–0.75 to export_linkage, C.* CALLS stay 0, 27 cgo files gain a flagged preamble range. Will follow up as a PR comment.

#1932 tracks the family.

@github-actions

Copy link
Copy Markdown

Thanks for opening this — it has been seen, and it is queued.

This note is automated, but it is not a brush-off: it exists so you know where your PR stands instead of having to guess from silence.

Current review status: working through a backlog. 0.9.1-rc.1 is out, so the release freeze that held reviews is over — but it left a large queue of open pull requests behind it, and we are reading through them oldest-first. The background is in discussion #1144.

What that means for this PR, concretely:

  • It will not be closed for inactivity. No stale bot touches pull requests here.
  • It may still sit a while before a human reads it. That is on us, not on you.
  • Older PRs are read first, so a recent one is not being skipped — it is behind a queue.

Things that will genuinely speed it up whenever review does happen:

  • Keep it rebased on main — the tree is moving quickly right now, and a conflicting branch cannot be reviewed as the diff you intended.
  • Get CI green, or say which failures you believe are pre-existing.
  • Keep the change to one claim. Bundled features and refactors get split before they get merged, which costs you a round trip.
  • Every commit needs a sign-off (git commit -s) — CI enforces DCO.

If this fixes a bug, a reproduction we can run is worth more than a description of the symptom.

Thanks for contributing, and sorry in advance for the wait.

…le coverage

A cgo file is one file in two languages; cbm reads it with the Go
grammar only. Three bounded pieces of DeusData#1929 (the design-sized fourth -
parsing the preamble with the C grammar - stays open for maintainers):

1. //export linkage. The directive declares the func's C ABI symbol
   (cgo requires the name to match), yet C-side callers bound it by
   short-name luck - unique_name at 0.38-0.75, or died in a weak-match
   guard on a name collision. The Go extractor now records the directive
   (CBMDefinition.is_cgo_export, node property cgo_export:true), and
   both CALLS resolvers upgrade an exact-name C/C++ caller to strategy
   export_linkage at contract confidence. 22 luck-based edges on the
   measured repo become declared contracts.

2. C. pseudo-namespace veto. 'C' is reserved by go/build - no project
   symbol can be behind C.<ident>, so any binding is fabricated (the
   standing DeusData#1906-shaped hijack surface). New pure predicate
   cbm_go_suppress_cgo_callee vetoes such callees in both resolvers
   before any strategy can bind them.

3. Preamble coverage honesty. A cgo file parses CLEAN - the preamble is
   a comment to the Go grammar - so parse coverage claimed full indexing
   while every preamble definition (12 C functions in one measured file)
   was missing. The comment run directly above import "C" is now
   flagged as an unparsed region (parse_incomplete + error_ranges),
   the same best-effort detection signal as DeusData#963.

Reproduce-first (RED with the wiring stashed, GREEN restored):
extract_go_cgo_export_flag (exact-name gate, mismatch and plain
negatives, preamble range 3-5 flagged, cgo-without-preamble and plain
Go stay clean), pipeline_go_cgo_export_binds_by_contract (edge carries
export_linkage, was unique_name), pipeline_go_cgo_callee_never_binds_
project_symbol (C.helper + project decoy -> zero edges), and
go_cgo_callee_veto predicate units. 784 tests green across extraction/
pipeline/registry/lsp probes/go_lsp.

Part of DeusData#1929

Signed-off-by: Ilya Brykau <ilya.brykau@orca.security>
@ilyabrykau-orca

Copy link
Copy Markdown
Author

CI retrigger (no-op amend): security / codeql-gate polled 90×30s for the CodeQL analysis and exited on BLOCKED: CodeQL timeout — queue congestion, no findings involved (the SAST job itself was queued behind today's waves). Same runner-environment day as #1952. No semantic changes.

@ilyabrykau-orca
ilyabrykau-orca force-pushed the fix/go-cgo-export-linkage branch from 5dbcd53 to 4a34a1d Compare August 30, 2026 20:47
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.

1 participant