Skip to content

Safety rails & budgeting

Obfuscation multiplies IR. Left unchecked, a heavy annotation on a large function can blow up compile time and binary size. xollvm gates every transform on size thresholds and an IR-growth budget, so obfuscation degrades gracefully instead of exploding.

Function-size gates

Skip functions that are too big or too deeply nested before any pass touches them:

Flag Default Meaning
-obf-max-function-insts=<N> 0 (off) Skip functions with more than N instructions.
-obf-max-function-blocks=<N> 0 (off) Skip functions with more than N basic blocks.
-obf-max-loop-depth=<N> 0 (off) Skip functions whose loop nesting exceeds N.

0 disables a gate. These are global — they apply to every annotated function.

The IR-growth budget

Each function has a budget: a ceiling on how much its instruction count may grow across all passes. When a pass would exceed it, sites are throttled or skipped rather than emitted.

Flag Default Meaning
-obf-ir-budget-multiplier=<N> 50 Budget = insts_before × N (clamped by the max below). 0 = unlimited.
-obf-ir-budget-max=<N> 0 (off) Absolute per-function instruction ceiling. 0 = no hard cap.

So by default a function may grow up to 50× its original size, with no absolute cap. Tighten both for size-sensitive targets:

opt -passes=obfuscation app.ll -S -o app.obf.ll \
    -obf-ir-budget-multiplier=20 -obf-ir-budget-max=8000

Budgets are global, not per-annotation

Budget knobs cannot currently be expressed as annotation tokens — set them on the command line. Per-pass caps like maxSites / maxBlocks are per-annotation and stack on top of the budget.

Reading budget pressure

When the report shows many "skipped due to budget" entries, the function hit its ceiling. Two ways to respond:

  • Want more obfuscation: raise -obf-ir-budget-multiplier / -obf-ir-budget-max.
  • Want smaller output: lower per-pass prob, maxDepth, loop, maxSites, or annotate fewer functions.
# see what was skipped and why
opt -passes=obfuscation app.ll -S -o app.obf.ll -obf-report-dir=obf_report -obf-verbose

The report JSON records budget utilisation per function; -obf-verbose prints skip reasons live. See Reports & CFG visualization.

Correctness rails

Beyond size, two flags guard correctness and debuggability:

Flag Default Meaning
-obf-verify off Run IR verification before/after each stage — catches an invalid transform close to its source.
-obf-debug-synthetic on Give inserted instructions synthetic line-0 debug locations so source steppers don't jump erratically.

Keep -obf-verify on while developing an annotation set; it turns a mysterious downstream crash into a precise "this pass produced invalid IR" error.