Question

Hardening flags are often discussed one at a time. This experiment examined what happens when compiler and linker choices meet heterogeneous ELF inputs, where some objects have different security properties from the final target.

The build matrix crossed GCC and Clang with bfd and lld, then exercised stack protection, FORTIFY, CET, stack-clash protection, RELRO/NOW, PIE, and CFI combinations.

Findings

For stack protection, FORTIFY, CET, and stack-clash protection, every tested applicable case reached the expected full state: 126 full results, two absent cases, and no partial results. RELRO/NOW succeeded in all eight Clang cases.

PIE was the revealing exception. The test set produced 130 successes and 126 failures. The 63 identical failure cases occurred with each compiler/linker pairing, which isolates the failure to the heterogeneous non-PIE-to-PIE input condition instead of any one toolchain.

CFI was enforced for homogeneous hardened inputs. Unsupported-to-unsupported and unsupported-to-hardened combinations did not gain enforcement merely from the final link, and successful comparable builds showed no semantic disagreement across the tested toolchains.

Takeaway

The results support a practical rule: final-link flags cannot always repair incompatible properties already present in object files. Build provenance and object-level assumptions deserve a place in hardening reviews.

Boundary

The matrix describes these tested compilers, linkers, flags, and inputs. It should guide a reproduction or a build audit, not stand in for universal behaviour across ELF ecosystems.