@vigolium/piolium 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (271) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +117 -0
  3. package/agents/access-auditor.md +300 -0
  4. package/agents/assumption-breaker.md +154 -0
  5. package/agents/attack-designer.md +116 -0
  6. package/agents/code-scanner.md +139 -0
  7. package/agents/concurrency-auditor.md +238 -0
  8. package/agents/confirm-writer.md +257 -0
  9. package/agents/context-reviewer.md +274 -0
  10. package/agents/cross-verifier.md +165 -0
  11. package/agents/cve-scout.md +381 -0
  12. package/agents/env-builder.md +282 -0
  13. package/agents/env-profiler.md +205 -0
  14. package/agents/evidence-collector.md +140 -0
  15. package/agents/finding-grader.md +142 -0
  16. package/agents/finding-writer.md +148 -0
  17. package/agents/flow-tracer.md +106 -0
  18. package/agents/goal-backtracer.md +146 -0
  19. package/agents/history-miner.md +467 -0
  20. package/agents/independent-verifier.md +118 -0
  21. package/agents/intent-mapper.md +183 -0
  22. package/agents/longshot-collector.md +128 -0
  23. package/agents/longshot-prober.md +126 -0
  24. package/agents/patch-auditor.md +73 -0
  25. package/agents/poc-author.md +124 -0
  26. package/agents/poc-runner.md +194 -0
  27. package/agents/probe-lead.md +269 -0
  28. package/agents/red-challenger.md +101 -0
  29. package/agents/report-composer.md +208 -0
  30. package/agents/review-adjudicator.md +216 -0
  31. package/agents/spec-auditor.md +155 -0
  32. package/agents/taint-tracer.md +265 -0
  33. package/agents/test-locator.md +209 -0
  34. package/agents/threat-modeler.md +132 -0
  35. package/agents/variant-scanner.md +108 -0
  36. package/agents/variant-spotter.md +110 -0
  37. package/bin/piolium.mjs +376 -0
  38. package/extensions/piolium/_vendor/yaml.bundle.d.mts +6 -0
  39. package/extensions/piolium/_vendor/yaml.bundle.mjs +139 -0
  40. package/extensions/piolium/agent-runner.ts +322 -0
  41. package/extensions/piolium/agents.ts +266 -0
  42. package/extensions/piolium/audit-state.ts +522 -0
  43. package/extensions/piolium/bundled-resources.ts +97 -0
  44. package/extensions/piolium/candidate-scan.ts +966 -0
  45. package/extensions/piolium/command-target.ts +177 -0
  46. package/extensions/piolium/console-stream.ts +57 -0
  47. package/extensions/piolium/export-results.ts +380 -0
  48. package/extensions/piolium/findings.ts +448 -0
  49. package/extensions/piolium/heartbeat.ts +182 -0
  50. package/extensions/piolium/help.ts +234 -0
  51. package/extensions/piolium/index.ts +1865 -0
  52. package/extensions/piolium/longshot.ts +530 -0
  53. package/extensions/piolium/matcher-suggestions.ts +196 -0
  54. package/extensions/piolium/matcher-utils.ts +83 -0
  55. package/extensions/piolium/modes/balanced.ts +750 -0
  56. package/extensions/piolium/modes/confirm-bootstrap.ts +186 -0
  57. package/extensions/piolium/modes/confirm.ts +697 -0
  58. package/extensions/piolium/modes/deep.ts +917 -0
  59. package/extensions/piolium/modes/diff.ts +177 -0
  60. package/extensions/piolium/modes/lite.ts +540 -0
  61. package/extensions/piolium/modes/longshot.ts +595 -0
  62. package/extensions/piolium/modes/merge.ts +204 -0
  63. package/extensions/piolium/modes/phase-runner.ts +267 -0
  64. package/extensions/piolium/modes/reinvest.ts +546 -0
  65. package/extensions/piolium/modes/revisit.ts +279 -0
  66. package/extensions/piolium/modes.ts +48 -0
  67. package/extensions/piolium/phase-labels.ts +123 -0
  68. package/extensions/piolium/phase-status-strip.ts +92 -0
  69. package/extensions/piolium/prompt-prefix-editor.ts +39 -0
  70. package/extensions/piolium/providers/anthropic-vertex.ts +836 -0
  71. package/extensions/piolium/recon.ts +409 -0
  72. package/extensions/piolium/result-stats.ts +105 -0
  73. package/extensions/piolium/retry.ts +120 -0
  74. package/extensions/piolium/scheduler.ts +212 -0
  75. package/extensions/piolium/secrets.ts +368 -0
  76. package/extensions/piolium/tools/web-tools.ts +148 -0
  77. package/package.json +77 -0
  78. package/skills/agentic-actions-auditor/SKILL.md +327 -0
  79. package/skills/agentic-actions-auditor/references/action-profiles.md +186 -0
  80. package/skills/agentic-actions-auditor/references/cross-file-resolution.md +209 -0
  81. package/skills/agentic-actions-auditor/references/foundations.md +94 -0
  82. package/skills/agentic-actions-auditor/references/vector-a-env-var-intermediary.md +77 -0
  83. package/skills/agentic-actions-auditor/references/vector-b-direct-expression-injection.md +83 -0
  84. package/skills/agentic-actions-auditor/references/vector-c-cli-data-fetch.md +83 -0
  85. package/skills/agentic-actions-auditor/references/vector-d-pr-target-checkout.md +88 -0
  86. package/skills/agentic-actions-auditor/references/vector-e-error-log-injection.md +88 -0
  87. package/skills/agentic-actions-auditor/references/vector-f-subshell-expansion.md +82 -0
  88. package/skills/agentic-actions-auditor/references/vector-g-eval-of-ai-output.md +91 -0
  89. package/skills/agentic-actions-auditor/references/vector-h-dangerous-sandbox-configs.md +102 -0
  90. package/skills/agentic-actions-auditor/references/vector-i-wildcard-allowlists.md +88 -0
  91. package/skills/audit/SKILL.md +562 -0
  92. package/skills/audit/assets/icon.svg +7 -0
  93. package/skills/audit/hooks/scripts/validate_phase_output.py +550 -0
  94. package/skills/audit/references/adversarial-review.md +148 -0
  95. package/skills/audit/references/architecture-aware-sast.md +306 -0
  96. package/skills/audit/references/audit-workflow.md +737 -0
  97. package/skills/audit/references/chamber-protocol.md +384 -0
  98. package/skills/audit/references/creative-attack-modes.md +221 -0
  99. package/skills/audit/references/deep-analysis.md +273 -0
  100. package/skills/audit/references/domain-attack-playbooks.md +1129 -0
  101. package/skills/audit/references/knowledge-base-template.md +513 -0
  102. package/skills/audit/references/real-env-validation.md +191 -0
  103. package/skills/audit/references/report-templates.md +417 -0
  104. package/skills/audit/references/triage-and-prereqs.md +134 -0
  105. package/skills/audit/scripts/consolidate_drafts.py +554 -0
  106. package/skills/audit/scripts/partition_findings.py +152 -0
  107. package/skills/audit/scripts/rg-hotspots.sh +121 -0
  108. package/skills/audit/scripts/stamp_file_state.py +349 -0
  109. package/skills/code-reviewer/SKILL.md +65 -0
  110. package/skills/codeql/SKILL.md +281 -0
  111. package/skills/codeql/references/build-fixes.md +90 -0
  112. package/skills/codeql/references/diagnostic-query-templates.md +339 -0
  113. package/skills/codeql/references/extension-yaml-format.md +209 -0
  114. package/skills/codeql/references/important-only-suite.md +153 -0
  115. package/skills/codeql/references/language-details.md +207 -0
  116. package/skills/codeql/references/macos-arm64e-workaround.md +179 -0
  117. package/skills/codeql/references/performance-tuning.md +111 -0
  118. package/skills/codeql/references/quality-assessment.md +172 -0
  119. package/skills/codeql/references/ruleset-catalog.md +63 -0
  120. package/skills/codeql/references/run-all-suite.md +92 -0
  121. package/skills/codeql/references/sarif-processing.md +79 -0
  122. package/skills/codeql/references/threat-models.md +51 -0
  123. package/skills/codeql/workflows/build-database.md +280 -0
  124. package/skills/codeql/workflows/create-data-extensions.md +261 -0
  125. package/skills/codeql/workflows/run-analysis.md +301 -0
  126. package/skills/differential-review/SKILL.md +220 -0
  127. package/skills/differential-review/adversarial.md +203 -0
  128. package/skills/differential-review/methodology.md +234 -0
  129. package/skills/differential-review/patterns.md +300 -0
  130. package/skills/differential-review/reporting.md +369 -0
  131. package/skills/fp-check/SKILL.md +125 -0
  132. package/skills/fp-check/references/bug-class-verification.md +114 -0
  133. package/skills/fp-check/references/deep-verification.md +143 -0
  134. package/skills/fp-check/references/evidence-templates.md +91 -0
  135. package/skills/fp-check/references/false-positive-patterns.md +115 -0
  136. package/skills/fp-check/references/gate-reviews.md +27 -0
  137. package/skills/fp-check/references/standard-verification.md +78 -0
  138. package/skills/insecure-defaults/SKILL.md +117 -0
  139. package/skills/insecure-defaults/references/examples.md +409 -0
  140. package/skills/last30days/SKILL.md +444 -0
  141. package/skills/sarif-parsing/SKILL.md +483 -0
  142. package/skills/sarif-parsing/resources/jq-queries.md +162 -0
  143. package/skills/sarif-parsing/resources/sarif_helpers.py +331 -0
  144. package/skills/security-threat-model/LICENSE.txt +201 -0
  145. package/skills/security-threat-model/SKILL.md +81 -0
  146. package/skills/security-threat-model/agents/openai.yaml +4 -0
  147. package/skills/security-threat-model/references/prompt-template.md +255 -0
  148. package/skills/security-threat-model/references/security-controls-and-assets.md +32 -0
  149. package/skills/semgrep/SKILL.md +212 -0
  150. package/skills/semgrep/references/rulesets.md +162 -0
  151. package/skills/semgrep/references/scan-modes.md +110 -0
  152. package/skills/semgrep/references/scanner-task-prompt.md +140 -0
  153. package/skills/semgrep/scripts/merge_sarif.py +203 -0
  154. package/skills/semgrep/workflows/scan-workflow.md +311 -0
  155. package/skills/semgrep-rule-creator/SKILL.md +168 -0
  156. package/skills/semgrep-rule-creator/references/quick-reference.md +202 -0
  157. package/skills/semgrep-rule-creator/references/workflow.md +240 -0
  158. package/skills/semgrep-rule-variant-creator/SKILL.md +205 -0
  159. package/skills/semgrep-rule-variant-creator/references/applicability-analysis.md +250 -0
  160. package/skills/semgrep-rule-variant-creator/references/language-syntax-guide.md +324 -0
  161. package/skills/semgrep-rule-variant-creator/references/workflow.md +518 -0
  162. package/skills/sharp-edges/SKILL.md +292 -0
  163. package/skills/sharp-edges/references/auth-patterns.md +252 -0
  164. package/skills/sharp-edges/references/case-studies.md +274 -0
  165. package/skills/sharp-edges/references/config-patterns.md +333 -0
  166. package/skills/sharp-edges/references/crypto-apis.md +190 -0
  167. package/skills/sharp-edges/references/lang-c.md +205 -0
  168. package/skills/sharp-edges/references/lang-csharp.md +285 -0
  169. package/skills/sharp-edges/references/lang-go.md +270 -0
  170. package/skills/sharp-edges/references/lang-java.md +263 -0
  171. package/skills/sharp-edges/references/lang-javascript.md +269 -0
  172. package/skills/sharp-edges/references/lang-kotlin.md +265 -0
  173. package/skills/sharp-edges/references/lang-php.md +245 -0
  174. package/skills/sharp-edges/references/lang-python.md +274 -0
  175. package/skills/sharp-edges/references/lang-ruby.md +273 -0
  176. package/skills/sharp-edges/references/lang-rust.md +272 -0
  177. package/skills/sharp-edges/references/lang-swift.md +287 -0
  178. package/skills/sharp-edges/references/language-specific.md +588 -0
  179. package/skills/spec-to-code-compliance/SKILL.md +357 -0
  180. package/skills/spec-to-code-compliance/resources/COMPLETENESS_CHECKLIST.md +69 -0
  181. package/skills/spec-to-code-compliance/resources/IR_EXAMPLES.md +417 -0
  182. package/skills/spec-to-code-compliance/resources/OUTPUT_REQUIREMENTS.md +105 -0
  183. package/skills/supply-chain-risk-auditor/SKILL.md +67 -0
  184. package/skills/supply-chain-risk-auditor/resources/results-template.md +41 -0
  185. package/skills/variant-analysis/METHODOLOGY.md +327 -0
  186. package/skills/variant-analysis/SKILL.md +142 -0
  187. package/skills/variant-analysis/resources/codeql/cpp.ql +119 -0
  188. package/skills/variant-analysis/resources/codeql/go.ql +69 -0
  189. package/skills/variant-analysis/resources/codeql/java.ql +71 -0
  190. package/skills/variant-analysis/resources/codeql/javascript.ql +63 -0
  191. package/skills/variant-analysis/resources/codeql/python.ql +80 -0
  192. package/skills/variant-analysis/resources/semgrep/cpp.yaml +98 -0
  193. package/skills/variant-analysis/resources/semgrep/go.yaml +63 -0
  194. package/skills/variant-analysis/resources/semgrep/java.yaml +61 -0
  195. package/skills/variant-analysis/resources/semgrep/javascript.yaml +60 -0
  196. package/skills/variant-analysis/resources/semgrep/python.yaml +72 -0
  197. package/skills/variant-analysis/resources/variant-report-template.md +75 -0
  198. package/skills/vuln-report/SKILL.md +137 -0
  199. package/skills/vuln-report/agents/openai.yaml +4 -0
  200. package/skills/vuln-report/references/report-template.md +135 -0
  201. package/skills/wooyun-legacy/SKILL.md +367 -0
  202. package/skills/wooyun-legacy/references/bank-penetration.md +222 -0
  203. package/skills/wooyun-legacy/references/checklists/command-execution-checklist.md +119 -0
  204. package/skills/wooyun-legacy/references/checklists/csrf-checklist.md +74 -0
  205. package/skills/wooyun-legacy/references/checklists/file-upload-checklist.md +108 -0
  206. package/skills/wooyun-legacy/references/checklists/info-disclosure-checklist.md +114 -0
  207. package/skills/wooyun-legacy/references/checklists/logic-flaws-checklist.md +95 -0
  208. package/skills/wooyun-legacy/references/checklists/misconfig-checklist.md +124 -0
  209. package/skills/wooyun-legacy/references/checklists/path-traversal-checklist.md +87 -0
  210. package/skills/wooyun-legacy/references/checklists/rce-checklist.md +93 -0
  211. package/skills/wooyun-legacy/references/checklists/sql-injection-checklist.md +97 -0
  212. package/skills/wooyun-legacy/references/checklists/ssrf-checklist.md +99 -0
  213. package/skills/wooyun-legacy/references/checklists/unauthorized-access-checklist.md +89 -0
  214. package/skills/wooyun-legacy/references/checklists/weak-password-checklist.md +115 -0
  215. package/skills/wooyun-legacy/references/checklists/xss-checklist.md +103 -0
  216. package/skills/wooyun-legacy/references/checklists/xxe-checklist.md +130 -0
  217. package/skills/wooyun-legacy/references/info-disclosure.md +975 -0
  218. package/skills/wooyun-legacy/references/logic-flaws.md +721 -0
  219. package/skills/wooyun-legacy/references/path-traversal.md +1191 -0
  220. package/skills/wooyun-legacy/references/telecom-penetration.md +156 -0
  221. package/skills/wooyun-legacy/references/unauthorized-access.md +980 -0
  222. package/skills/wooyun-legacy/references/xss.md +746 -0
  223. package/skills/zeroize-audit/SKILL.md +371 -0
  224. package/skills/zeroize-audit/configs/c.yaml +21 -0
  225. package/skills/zeroize-audit/configs/default.yaml +128 -0
  226. package/skills/zeroize-audit/configs/rust.yaml +83 -0
  227. package/skills/zeroize-audit/prompts/report_template.md +238 -0
  228. package/skills/zeroize-audit/prompts/system.md +163 -0
  229. package/skills/zeroize-audit/prompts/task.md +97 -0
  230. package/skills/zeroize-audit/references/compile-commands.md +231 -0
  231. package/skills/zeroize-audit/references/detection-strategy.md +191 -0
  232. package/skills/zeroize-audit/references/ir-analysis.md +252 -0
  233. package/skills/zeroize-audit/references/mcp-analysis.md +221 -0
  234. package/skills/zeroize-audit/references/poc-generation.md +470 -0
  235. package/skills/zeroize-audit/references/rust-zeroization-patterns.md +867 -0
  236. package/skills/zeroize-audit/schemas/input.json +83 -0
  237. package/skills/zeroize-audit/schemas/output.json +140 -0
  238. package/skills/zeroize-audit/tools/analyze_asm.sh +202 -0
  239. package/skills/zeroize-audit/tools/analyze_cfg.py +381 -0
  240. package/skills/zeroize-audit/tools/analyze_heap.sh +211 -0
  241. package/skills/zeroize-audit/tools/analyze_ir_semantic.py +429 -0
  242. package/skills/zeroize-audit/tools/diff_ir.sh +135 -0
  243. package/skills/zeroize-audit/tools/diff_rust_mir.sh +189 -0
  244. package/skills/zeroize-audit/tools/emit_asm.sh +67 -0
  245. package/skills/zeroize-audit/tools/emit_ir.sh +77 -0
  246. package/skills/zeroize-audit/tools/emit_rust_asm.sh +178 -0
  247. package/skills/zeroize-audit/tools/emit_rust_ir.sh +150 -0
  248. package/skills/zeroize-audit/tools/emit_rust_mir.sh +158 -0
  249. package/skills/zeroize-audit/tools/extract_compile_flags.py +284 -0
  250. package/skills/zeroize-audit/tools/generate_poc.py +1329 -0
  251. package/skills/zeroize-audit/tools/mcp/apply_confidence_gates.py +113 -0
  252. package/skills/zeroize-audit/tools/mcp/check_mcp.sh +68 -0
  253. package/skills/zeroize-audit/tools/mcp/normalize_mcp_evidence.py +125 -0
  254. package/skills/zeroize-audit/tools/scripts/check_llvm_patterns.py +481 -0
  255. package/skills/zeroize-audit/tools/scripts/check_mir_patterns.py +554 -0
  256. package/skills/zeroize-audit/tools/scripts/check_rust_asm.py +424 -0
  257. package/skills/zeroize-audit/tools/scripts/check_rust_asm_aarch64.py +300 -0
  258. package/skills/zeroize-audit/tools/scripts/check_rust_asm_x86.py +283 -0
  259. package/skills/zeroize-audit/tools/scripts/find_dangerous_apis.py +375 -0
  260. package/skills/zeroize-audit/tools/scripts/semantic_audit.py +923 -0
  261. package/skills/zeroize-audit/tools/track_dataflow.sh +196 -0
  262. package/skills/zeroize-audit/tools/validate_rust_toolchain.sh +298 -0
  263. package/skills/zeroize-audit/workflows/phase-0-preflight.md +150 -0
  264. package/skills/zeroize-audit/workflows/phase-1-source-analysis.md +144 -0
  265. package/skills/zeroize-audit/workflows/phase-2-compiler-analysis.md +139 -0
  266. package/skills/zeroize-audit/workflows/phase-3-interim-report.md +46 -0
  267. package/skills/zeroize-audit/workflows/phase-4-poc-generation.md +46 -0
  268. package/skills/zeroize-audit/workflows/phase-5-poc-validation.md +136 -0
  269. package/skills/zeroize-audit/workflows/phase-6-final-report.md +44 -0
  270. package/skills/zeroize-audit/workflows/phase-7-test-generation.md +42 -0
  271. package/themes/piolium-srcery.json +94 -0
@@ -0,0 +1,158 @@
1
+ #!/usr/bin/env bash
2
+ # emit_rust_mir.sh — Emit Rust MIR for zeroize analysis.
3
+ #
4
+ # Exit codes:
5
+ # 0 success
6
+ # 1 build/output failure
7
+ # 2 argument error
8
+
9
+ set -euo pipefail
10
+
11
+ usage() {
12
+ cat <<'EOF'
13
+ Usage:
14
+ emit_rust_mir.sh --manifest <Cargo.toml> --out <path> [options] [-- <extra cargo rustc args>]
15
+
16
+ Options:
17
+ --manifest <file> Cargo manifest path (required)
18
+ --out <path> Output .mir file or directory (required)
19
+ --opt <O0|O1|O2|O3> Opt level (default: O0)
20
+ --crate <pkg> Workspace package (-p)
21
+ --bin <target> Build only a specific bin target
22
+ --lib Build only the lib target
23
+ --help Show this help text
24
+
25
+ Examples:
26
+ emit_rust_mir.sh --manifest Cargo.toml --opt O0 --out /tmp/crate.O0.mir
27
+ emit_rust_mir.sh --manifest Cargo.toml --out /tmp/zeroize_mir
28
+ EOF
29
+ }
30
+
31
+ die_arg() {
32
+ echo "emit_rust_mir.sh: $*" >&2
33
+ exit 2
34
+ }
35
+
36
+ die_run() {
37
+ echo "emit_rust_mir.sh: $*" >&2
38
+ exit 1
39
+ }
40
+
41
+ require_value() {
42
+ local opt="$1"
43
+ local val="${2-}"
44
+ [[ -n "$val" ]] || die_arg "missing value for ${opt}"
45
+ }
46
+
47
+ MANIFEST=""
48
+ OUT=""
49
+ OPT="O0"
50
+ CRATE=""
51
+ BIN_TARGET=""
52
+ LIB_TARGET=false
53
+ EXTRA_ARGS=()
54
+
55
+ while [[ $# -gt 0 ]]; do
56
+ case "$1" in
57
+ --manifest)
58
+ require_value "$1" "${2-}"
59
+ MANIFEST="$2"
60
+ shift 2
61
+ ;;
62
+ --out)
63
+ require_value "$1" "${2-}"
64
+ OUT="$2"
65
+ shift 2
66
+ ;;
67
+ --opt)
68
+ require_value "$1" "${2-}"
69
+ OPT="$2"
70
+ shift 2
71
+ ;;
72
+ --crate)
73
+ require_value "$1" "${2-}"
74
+ CRATE="$2"
75
+ shift 2
76
+ ;;
77
+ --bin)
78
+ require_value "$1" "${2-}"
79
+ BIN_TARGET="$2"
80
+ shift 2
81
+ ;;
82
+ --lib)
83
+ LIB_TARGET=true
84
+ shift
85
+ ;;
86
+ --help | -h)
87
+ usage
88
+ exit 0
89
+ ;;
90
+ --)
91
+ shift
92
+ EXTRA_ARGS=("$@")
93
+ break
94
+ ;;
95
+ *)
96
+ die_arg "unknown argument: $1"
97
+ ;;
98
+ esac
99
+ done
100
+
101
+ [[ -n "$MANIFEST" ]] || die_arg "--manifest is required"
102
+ [[ -n "$OUT" ]] || die_arg "--out is required"
103
+ [[ -f "$MANIFEST" ]] || die_run "manifest not found: $MANIFEST"
104
+ [[ -n "$BIN_TARGET" && "$LIB_TARGET" == true ]] && die_arg "--bin and --lib are mutually exclusive"
105
+
106
+ case "$OPT" in
107
+ O0) LEVEL="0" ;;
108
+ O1) LEVEL="1" ;;
109
+ O2) LEVEL="2" ;;
110
+ O3) LEVEL="3" ;;
111
+ *) die_arg "unsupported opt level: $OPT (use O0, O1, O2, O3)" ;;
112
+ esac
113
+
114
+ OUT_IS_FILE=false
115
+ if [[ "$OUT" == *.mir ]]; then
116
+ OUT_IS_FILE=true
117
+ mkdir -p "$(dirname "$OUT")"
118
+ else
119
+ mkdir -p "$OUT"
120
+ fi
121
+
122
+ CARGO_ARGS=(+nightly rustc --manifest-path "$MANIFEST")
123
+ [[ -n "$CRATE" ]] && CARGO_ARGS+=("-p" "$CRATE")
124
+ [[ -n "$BIN_TARGET" ]] && CARGO_ARGS+=("--bin" "$BIN_TARGET")
125
+ [[ "$LIB_TARGET" == true ]] && CARGO_ARGS+=("--lib")
126
+
127
+ TARGET_DIR="${TMPDIR:-/tmp}/zeroize_rust_mir_${LEVEL}_$$"
128
+ rm -rf "$TARGET_DIR"
129
+ mkdir -p "$TARGET_DIR"
130
+
131
+ echo "=== emit_rust_mir.sh ==="
132
+ echo "manifest: $MANIFEST"
133
+ echo "opt: $OPT"
134
+ echo "target: $TARGET_DIR"
135
+ echo "output: $OUT"
136
+
137
+ if ! CARGO_TARGET_DIR="$TARGET_DIR" cargo "${CARGO_ARGS[@]}" \
138
+ "${EXTRA_ARGS[@]+"${EXTRA_ARGS[@]}"}" \
139
+ -- --emit=mir -C opt-level="$LEVEL"; then
140
+ die_run "cargo rustc failed for opt=${OPT}"
141
+ fi
142
+
143
+ declare -a MIR_FILES=()
144
+ while IFS= read -r file; do
145
+ MIR_FILES+=("$file")
146
+ done < <(find "$TARGET_DIR" -type f -name "*.mir" | LC_ALL=C sort)
147
+
148
+ [[ "${#MIR_FILES[@]}" -gt 0 ]] || die_run "no .mir files found under $TARGET_DIR"
149
+
150
+ if [[ "$OUT_IS_FILE" == true ]]; then
151
+ : >"$OUT"
152
+ for file in "${MIR_FILES[@]}"; do
153
+ cat "$file" >>"$OUT"
154
+ done
155
+ [[ -s "$OUT" ]] || die_run "emitted MIR is empty: $OUT"
156
+ else
157
+ cp "${MIR_FILES[@]}" "$OUT/"
158
+ fi
@@ -0,0 +1,284 @@
1
+ #!/usr/bin/env python3
2
+ # /// script
3
+ # requires-python = ">=3.11"
4
+ # dependencies = []
5
+ # ///
6
+ """
7
+ Extract per-TU compilation flags from compile_commands.json.
8
+
9
+ Reads the compile database for a given source file and emits the compilation
10
+ flags suitable for single-file LLVM IR or assembly emission via clang. Output
11
+ and dependency-generation flags are stripped.
12
+
13
+ Usage:
14
+ python extract_compile_flags.py \\
15
+ --compile-db compile_commands.json \\
16
+ --src path/to/file.c \\
17
+ [--format shell|json|lines] \\
18
+ [--working-dir /override/cwd]
19
+
20
+ # Recommended: capture as a bash array (works in both bash and zsh):
21
+ FLAGS=()
22
+ while IFS= read -r flag; do FLAGS+=("$flag"); done < <(
23
+ python {baseDir}/tools/extract_compile_flags.py \\
24
+ --compile-db build/compile_commands.json \\
25
+ --src src/crypto.c --format lines)
26
+ {baseDir}/tools/emit_ir.sh --src src/crypto.c --out /tmp/out.ll --opt O2 -- "${FLAGS[@]}"
27
+
28
+ # Get as JSON list:
29
+ python {baseDir}/tools/extract_compile_flags.py \\
30
+ --compile-db build/compile_commands.json \\
31
+ --src src/crypto.c \\
32
+ --format json
33
+
34
+ Exit codes:
35
+ 0 flags written to stdout
36
+ 1 compile_commands.json not found or contains invalid JSON
37
+ 2 source file not found in the compile database
38
+ """
39
+
40
+ import argparse
41
+ import contextlib
42
+ import json
43
+ import re
44
+ import shlex
45
+ import sys
46
+ from pathlib import Path
47
+
48
+ # ---------------------------------------------------------------------------
49
+ # Flags to strip: irrelevant or harmful for single-file IR/ASM emission.
50
+ # Ordering matters for the "takes an argument" set — we must skip the next
51
+ # token too.
52
+ # ---------------------------------------------------------------------------
53
+
54
+ # Flags that consume the next token as their argument and should be stripped.
55
+ _STRIP_WITH_ARG = frozenset(["-o", "-MF", "-MT", "-MQ"])
56
+
57
+ # Single-token flags to strip (no argument consumed).
58
+ _STRIP_STANDALONE = frozenset(
59
+ [
60
+ "-c",
61
+ "-MD",
62
+ "-MMD",
63
+ "-MP",
64
+ "-MG",
65
+ "-pipe",
66
+ "-save-temps",
67
+ "-gsplit-dwarf",
68
+ ]
69
+ )
70
+
71
+ # Prefix patterns: strip any flag whose string starts with one of these.
72
+ _STRIP_PREFIXES = (
73
+ "-fcrash-diagnostics-dir",
74
+ "-fmodule-file=",
75
+ "-fmodules-cache-path=",
76
+ "-fpch-preprocess",
77
+ "--serialize-diagnostics",
78
+ "-fdebug-prefix-map=",
79
+ "--debug-prefix-map=",
80
+ "-iprefix",
81
+ "-iwithprefix",
82
+ "-iwithprefixbefore",
83
+ "-fprofile-generate",
84
+ "-fprofile-use=",
85
+ "-fprofile-instr-generate",
86
+ "-fprofile-instr-use=",
87
+ "-fcoverage-mapping",
88
+ )
89
+
90
+ # Regex for "attached" forms of strip-with-arg flags, e.g. "-MFdepfile" or "-MF=depfile".
91
+ # These are single tokens that begin with one of the strip-with-arg prefixes.
92
+ _STRIP_ATTACHED_RE = re.compile(r"^(?:-o|-MF|-MT|-MQ)(?:=?.+)$")
93
+
94
+
95
+ def _should_strip(flag: str) -> bool:
96
+ """Return True if this flag token should be removed from the output."""
97
+ if flag in _STRIP_STANDALONE:
98
+ return True
99
+ if _STRIP_ATTACHED_RE.match(flag):
100
+ return True
101
+ return any(flag.startswith(prefix) for prefix in _STRIP_PREFIXES)
102
+
103
+
104
+ def _extract_flags(raw_flags: list[str]) -> list[str]:
105
+ """
106
+ Filter a list of raw flag tokens (excluding the compiler executable at index 0
107
+ and the source file argument) down to the build-relevant subset.
108
+ """
109
+ result: list[str] = []
110
+ skip_next = False
111
+
112
+ for token in raw_flags:
113
+ if skip_next:
114
+ skip_next = False
115
+ continue
116
+
117
+ # Strip-with-arg: consume this token and the next.
118
+ if token in _STRIP_WITH_ARG:
119
+ skip_next = True
120
+ continue
121
+
122
+ # Other strip conditions (standalone and prefixed).
123
+ if _should_strip(token):
124
+ continue
125
+
126
+ result.append(token)
127
+
128
+ return result
129
+
130
+
131
+ def _parse_command_string(command: str) -> list[str]:
132
+ """Split a shell command string into tokens using POSIX shlex rules."""
133
+ try:
134
+ return shlex.split(command)
135
+ except ValueError as exc:
136
+ # Malformed quoting — best-effort split on whitespace.
137
+ sys.stderr.write(f"Warning: shlex.split failed ({exc}), falling back to whitespace split\n")
138
+ return command.split()
139
+
140
+
141
+ def _normalize_path(path_str: str, directory: str) -> Path:
142
+ """Resolve a (possibly relative) path against a directory to an absolute Path."""
143
+ p = Path(path_str)
144
+ if not p.is_absolute():
145
+ p = Path(directory) / p
146
+ return p.resolve()
147
+
148
+
149
+ def find_entry(db: list, src: str, working_dir: str | None = None) -> dict | None:
150
+ """
151
+ Find the compile_commands.json entry for the given source file.
152
+
153
+ Matching is done by resolving both the entry's 'file' field and the
154
+ requested 'src' to absolute paths and comparing them. The first match
155
+ is returned (some projects emit duplicates for different configurations).
156
+ """
157
+ src_path = Path(src)
158
+ if working_dir and not src_path.is_absolute():
159
+ src_path = Path(working_dir) / src_path
160
+ with contextlib.suppress(OSError):
161
+ src_path = src_path.resolve() # file may not exist on disk; compare string form
162
+
163
+ for entry in db:
164
+ entry_dir = entry.get("directory", "")
165
+ entry_file = entry.get("file", "")
166
+ try:
167
+ entry_path = _normalize_path(entry_file, entry_dir)
168
+ except OSError:
169
+ entry_path = Path(entry_file)
170
+
171
+ if entry_path == src_path:
172
+ return entry
173
+
174
+ # Second pass: basename comparison (handles minor path discrepancies).
175
+ src_basename = src_path.name
176
+ for entry in db:
177
+ entry_file = entry.get("file", "")
178
+ if Path(entry_file).name == src_basename:
179
+ return entry
180
+
181
+ return None
182
+
183
+
184
+ def get_raw_flags(entry: dict) -> list[str]:
185
+ """
186
+ Extract the raw flag tokens from a compile_commands.json entry.
187
+
188
+ Returns all tokens except the compiler executable (index 0) and the
189
+ source file argument. The caller is responsible for further filtering.
190
+ """
191
+ arguments: list[str] | None = entry.get("arguments")
192
+ if arguments is None:
193
+ command = entry.get("command", "")
194
+ arguments = _parse_command_string(command)
195
+
196
+ if not arguments:
197
+ return []
198
+
199
+ # Drop compiler executable (index 0) and the source file token.
200
+ src_file = entry.get("file", "")
201
+ raw: list[str] = []
202
+ for token in arguments[1:]:
203
+ # Skip the source file itself (it will be specified via --src to emit_ir.sh).
204
+ if token == src_file or (src_file and Path(token).name == Path(src_file).name):
205
+ continue
206
+ raw.append(token)
207
+
208
+ return raw
209
+
210
+
211
+ def main() -> None:
212
+ parser = argparse.ArgumentParser(
213
+ description="Extract per-TU compile flags from compile_commands.json.",
214
+ formatter_class=argparse.RawDescriptionHelpFormatter,
215
+ epilog=__doc__,
216
+ )
217
+ parser.add_argument(
218
+ "--compile-db",
219
+ required=True,
220
+ metavar="PATH",
221
+ help="Path to compile_commands.json",
222
+ )
223
+ parser.add_argument(
224
+ "--src",
225
+ required=True,
226
+ metavar="FILE",
227
+ help="Source file to look up in the compile database",
228
+ )
229
+ parser.add_argument(
230
+ "--format",
231
+ choices=["shell", "json", "lines"],
232
+ default="shell",
233
+ help=(
234
+ "Output format: 'shell' (space-separated, shell-quoted), 'json' list, "
235
+ "or 'lines' (one flag per line, for array consumption) (default: shell)"
236
+ ),
237
+ )
238
+ parser.add_argument(
239
+ "--working-dir",
240
+ metavar="DIR",
241
+ default=None,
242
+ help="Working directory for resolving relative --src paths (default: cwd)",
243
+ )
244
+ args = parser.parse_args()
245
+
246
+ # Load compile database.
247
+ db_path = Path(args.compile_db)
248
+ if not db_path.exists():
249
+ sys.stderr.write(f"Error: compile database not found: {db_path}\n")
250
+ sys.exit(1)
251
+
252
+ try:
253
+ db = json.loads(db_path.read_text())
254
+ except json.JSONDecodeError as exc:
255
+ sys.stderr.write(f"Error: invalid JSON in {db_path}: {exc}\n")
256
+ sys.exit(1)
257
+
258
+ if not isinstance(db, list):
259
+ sys.stderr.write(f"Error: expected a JSON array in {db_path}\n")
260
+ sys.exit(1)
261
+
262
+ # Find the entry for the requested source file.
263
+ entry = find_entry(db, args.src, args.working_dir)
264
+ if entry is None:
265
+ sys.stderr.write(f"Error: '{args.src}' not found in {db_path} ({len(db)} entries)\n")
266
+ sys.exit(2)
267
+
268
+ # Extract and filter flags.
269
+ raw = get_raw_flags(entry)
270
+ flags = _extract_flags(raw)
271
+
272
+ # Output.
273
+ if args.format == "json":
274
+ print(json.dumps(flags))
275
+ elif args.format == "lines":
276
+ for f in flags:
277
+ print(f)
278
+ else:
279
+ # Shell format: space-join of individually shell-quoted tokens.
280
+ print(" ".join(shlex.quote(f) for f in flags))
281
+
282
+
283
+ if __name__ == "__main__":
284
+ main()