Documentation Index
Fetch the complete documentation index at: https://mintlify.com/AFLplusplus/AFLplusplus/llms.txt
Use this file to discover all available pages before exploring further.
TL;DR
- Best performance: 10-25% faster than regular LLVM mode with guaranteed collision-free coverage
- Requirements: LLVM 12 or newer
- Compatible with: COMPCOV, CMPLOG, and instrument file listing
- Setup: Set
AR=llvm-ar RANLIB=llvm-ranlib AS=llvm-asif issues arise - Linker: Some targets need
LD=afl-clang-lto, others needLD=afl-ld-lto
Overview
LTO (Link-Time Optimization) mode provides collision-free edge coverage by instrumenting at link time when all compilation units are available. This solves the major problem of random basic block IDs causing edge collisions in the coverage map.The Collision Problem
With the standard 64KB map (2^16):- At just 256 instrumented blocks: 1 collision on average
- Typical targets have 10,000-50,000 blocks: 750-18,000 collisions!
- Result: Missed paths and degraded fuzzing efficiency
How LTO Mode Works
- Compile source files in LTO (Link-Time Optimization) mode
- At link time, collect all LTO files
- Instrument with non-colliding edge IDs
- Use LLVM’s
-fsanitize=coverageedge coverage style
Benefits
- 10-25% faster than regular LLVM mode
- Guaranteed collision-free edge coverage
- Better path discovery through accurate coverage
- AUTODICTIONARY: Automatic dictionary extraction
Tradeoffs
- Longer compile times, especially for binaries linked to instrumented libraries
- Sometimes much longer for complex projects
Requirements
LTO mode requires LLVM 12 or newer. LLVM 13-19 recommended.
Installing LLVM
The best way to install LLVM is via https://apt.llvm.org/:Building AFL++ with LTO Support
Usage
Basic Compilation
Useafl-clang-lto exactly like afl-clang-fast:
With Required Build Tools
Many targets require LTO-compatible build tools:You may need to add version suffixes like
llvm-ar-19, llvm-ranlib-19, etc.Setting the Linker
Some targets also need the linker set. Try both options:Example Build Output
From a libtiff build:Compatible Features
LTO mode works with these AFL++ features:Instrument File Listing
LAF-Intel / COMPCOV
AUTODICTIONARY Feature
LTO mode automatically generates dictionaries from string comparisons during compilation!
- Automatically extracted from string compare operations
- Embedded in the target binary
- Transferred to afl-fuzz on startup
- Improves coverage by 5-10% statistically
Disabling AUTODICTIONARY
If needed, disable it when starting afl-fuzz:Environment Variables
Set a fixed shared memory map address for additional speed. Recommended:
0x10000Document which edge ID was assigned to which function.Helps identify:
- Functions with variable bytes
- Functions touched by specific inputs
Disable the autodictionary feature at runtime.
Shared Library Instrumentation
If you must instrument shared libraries:Set during shared library compilation.
Set to the cumulative edge count of all previously compiled shared libraries.
Troubleshooting
Error: “archive has no index”
Error: “assembler command failed”
Solution: SetAS=llvm-as:
Compilation Failures
Test if the issue is with LTO or AFL++:Complex Target Examples
Example: ffmpeg
Example: WebKit jsc
Performance Comparison
| Mode | Speed | Collisions | Coverage |
|---|---|---|---|
| afl-clang-fast | Baseline | 750-18,000 | Degraded |
| afl-clang-lto | +10-25% | 0 | Optimal |
| + LTO_MAP_ADDR | +2-5% more | 0 | Optimal |
History
LTO mode development timeline:- Summer 2019: Initial concept by hexcoder-
- January 2020: First implementation via opt + custom linker
- Solution breakthrough: domenukk proposed edge splitting with incremental counters
- LLVM 12+: Native pass loading in linker solved all previous issues
Next Steps
Persistent Mode
Combine with persistent mode for maximum performance
CmpLog
Add CmpLog for Redqueen-style mutations
LAF-Intel
Split complex comparisons for better coverage
LLVM Mode
Fall back to regular LLVM mode if LTO doesn’t work

