AD6001: DisableIncrementalLinkingInReleaseBuilds¶
Summary¶
| Property | Value |
|---|---|
| ID | AD6001 |
| Name | DisableIncrementalLinkingInReleaseBuilds |
| Category | Performance |
| Severity | Warning |
| Applies to | PE (Windows) |
Description¶
Incremental linking support increases binary size and can reduce runtime performance. The support for incremental linking adds padding and other overhead to support the ability to modify a binary without a full link. The use of incrementally linked binaries may reduce the level of determinism because previous compilations will have lingering effects on subsequent compilations. Fully optimized release builds should not specify incremental linking.
Why This Matters¶
Incremental linking is a development convenience that has significant security and performance costs. Release builds with incremental linking enabled waste space, run slower, and create potential security vulnerabilities.
The .textbss Security Problem¶
Incremental linking creates a .textbss section that is both writable and executable:
.textbss section:
- Reserves space between functions
- Must be writable (for incremental updates)
- Must be executable (it's code space)
- Result: W+X memory = security vulnerability
This violates the W^X principle that's fundamental to exploit mitigation.
Performance Impact¶
| Aspect | Incremental | Full Link |
|---|---|---|
| Binary size | Larger (padding) | Smaller |
| Code locality | Poor (gaps) | Optimal |
| I-cache efficiency | Reduced | Better |
| Startup time | May be slower | Optimal |
Optimization Incompatibilities¶
Incremental linking disables key optimizations:
| Optimization | With Incremental | Without |
|---|---|---|
| /OPT:REF | Disabled | Active |
| /OPT:ICF | Disabled | Active |
| COMDAT folding | Disabled | Active |
| Dead code removal | Limited | Full |
Determinism Issues¶
Incremental build 1: Functions at offsets A, B, C
Incremental build 2: Functions at offsets A, B', C'
(B changed, gaps shifted)
Full rebuild: Functions at offsets X, Y, Z
(deterministic layout)
Non-deterministic builds complicate security auditing and reproducibility.
When Incremental Linking Is Appropriate¶
| Build Type | Incremental |
|---|---|
| Debug/Development | Yes (faster builds) |
| CI test builds | Maybe (balance) |
| Release/Production | No (never) |
| Security-critical | No (never) |
- Binary Size: Incremental linking adds padding between functions, increasing binary size
- Performance: The extra padding can reduce cache efficiency and increase code size
- Determinism: Incremental builds may have non-deterministic layouts
- Optimization: Full optimization passes work better without incremental linking constraints
- Security: Larger binaries have more attack surface
Detection Method¶
This rule checks for the presence of the .textbss section, which is created by the linker when incremental linking is enabled. This section reserves space for future function additions during incremental linking.
Resolution¶
For Command Line Builds¶
- Remove
/INCREMENTALfrom linker options - Or explicitly add
/INCREMENTAL:NO
For Visual Studio Projects¶
- Open Project Properties
- Navigate to Linker > General
- Set Enable Incremental Linking to No (/INCREMENTAL:NO)
For Release configurations, this should be the default. Check that you haven't overridden it.
In MSBuild¶
<ItemDefinitionGroup Condition="'$(Configuration)'=='Release'">
<Link>
<LinkIncremental>false</LinkIncremental>
</Link>
</ItemDefinitionGroup>
When to Ignore¶
- Debug builds intentionally use incremental linking for faster iteration
- This rule is specifically about release/production builds
Related Compiler Flags¶
| Flag | Effect |
|---|---|
/INCREMENTAL:NO |
Disable incremental linking |
/INCREMENTAL:YES |
Enable incremental linking |
/OPT:REF |
Remove unreferenced functions (incompatible with incremental) |
/OPT:ICF |
Enable COMDAT folding (incompatible with incremental) |
See Also¶
- AD6006: EnableLinkTimeCodeGeneration - LTCG is incompatible with incremental linking
- Microsoft Docs: /INCREMENTAL (Link Incrementally)