Skip to content

Force PIE on bootgen to fix PDI-generation segfault#3327

Merged
jgmelber merged 2 commits into
mainfrom
fix-bootgen-pie
Jul 13, 2026
Merged

Force PIE on bootgen to fix PDI-generation segfault#3327
jgmelber merged 2 commits into
mainfrom
fix-bootgen-pie

Conversation

@jgmelber

Copy link
Copy Markdown
Collaborator

Summary

Fixes a real, hardware-reproducible crash found while validating #3323 (ROCm mlir_aie wheel on Ryzen AI self-hosted runners): nearly every programming_examples/ test failed with

```
RuntimeError: [aiecc] Compilation failed with exit code 1:
Error: Command failed with exit code -2
Error message: Segmentation fault (core dumped)
Error generating PDI
```

on both `aie2-4col` and `aie2p-8col` — see full diagnosis in this comment.

Root cause: `bootgen` has no dependency on MLIR/LLVM (it only links `OpenSSL::SSL` + its own `bootgen-lib`), but it's configured as part of the same top-level CMake invocation as everything else, so it silently inherits whatever global compiler/linker defaults `find_package(MLIR)`/`include(HandleLLVMOptions)` set for that run. Building against the ROCm-built MLIR wheel flips `bootgen` from a PIE executable to a non-PIE one, while it still declares dynamic `NEEDED` libs and an `RPATH`. `auditwheel repair`'s `patchelf`-based RPATH rewrite (needed to point at vendored/renamed OpenSSL libs) then corrupts that non-standard layout — the binary `SIGSEGV`s (`SEGV_ACCERR`) jumping into its own non-executable `DYNAMIC` segment before `main()` even runs.

Confirmed via `strace`:
```
--- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_ACCERR, si_addr=0x4020c8} ---
```
`readelf -l` shows `0x4020c8` falls inside the `DYNAMIC` segment, which is mapped `RW` only — something is jumping there to execute code.

Fix: pin `POSITION_INDEPENDENT_CODE ON` directly on the `bootgen-lib` and `bootgen` CMake targets, so their ELF layout no longer depends on whatever the linked MLIR/LLVM package happens to set globally.

Verified locally:

  • Before: `bootgen -help` segfaults immediately — even under `LD_TRACE_LOADED_OBJECTS=1` (what `ldd` uses internally), i.e. before `bootgen`'s own code runs. ELF type: `EXEC`.
  • After (rebuilt `bootgen` target against the same ROCm MLIR content): ELF type is now `pie executable`, and `bootgen -help` runs correctly, printing the normal `Bootgen v2023.2` banner.
  • Also rebuilt `aiecc` (which links the same `bootgen-lib`) to confirm no regression there.

This blocks #3323 and #3326 (which depends on #3323 passing) — once merged, #3323 should be re-run against a wheel built with this fix.

Test plan

🤖 Generated with Claude Code

bootgen has no dependency on MLIR/LLVM (it only links OpenSSL::SSL and
its own bootgen-lib), but it's configured as part of the same CMake
invocation as the rest of mlir-aie, so it silently inherits whatever
global compiler/linker defaults find_package(MLIR)/
include(HandleLLVMOptions) set for that run.

Building against the ROCm-built MLIR wheel (see the rocm-mlir-distro
migration) flips bootgen from a PIE executable to a non-PIE one, while
it still declares dynamic NEEDED libs and an RPATH. auditwheel repair's
patchelf-based RPATH rewrite (needed to point at vendored/renamed
OpenSSL libs) then corrupts that non-standard layout: the resulting
binary SIGSEGVs (SEGV_ACCERR) jumping into its own non-executable
DYNAMIC segment before main() even runs, on real Ryzen AI hardware, not
just in a sandbox. This broke PDI/xclbin generation for nearly every
programming_examples/*.lit test in
#3323.

Pin POSITION_INDEPENDENT_CODE ON directly on bootgen-lib and bootgen so
their ELF layout no longer depends on whatever the MLIR/LLVM package
happens to set globally. Verified locally: before the fix, `bootgen
-help` segfaults immediately (even under LD_TRACE_LOADED_OBJECTS=1,
i.e. before bootgen's own code runs); after, it links as a normal PIE
executable and runs correctly.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@jgmelber jgmelber requested a review from abisca as a code owner July 13, 2026 17:19
Copilot AI review requested due to automatic review settings July 13, 2026 17:19

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR hardens the build configuration for the bootgen host tool so its ELF type/layout is stable across different top-level MLIR/LLVM build flag configurations (notably ROCm wheel builds), preventing a reproducible segfault during PDI generation after auditwheel repair rewrites RPATHs.

Changes:

  • Forces POSITION_INDEPENDENT_CODE ON on bootgen-lib to ensure it is compiled as PIC.
  • Forces POSITION_INDEPENDENT_CODE ON on the bootgen executable target to ensure it is built as PIE (where supported by the toolchain/CMake).
  • Adds in-file rationale documenting why target-local PIE/PIC is required (avoids inheriting MLIR/LLVM global flags).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@andrej andrej left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. Did make the comment a bit more terse. I just left a similar comment on a recent PR from Erika -- I feel like AI tends to create too many/too verbose comments that fill up my human context window.

Comment thread tools/bootgen/CMakeLists.txt Outdated
Co-authored-by: André Rösti <an.roesti@gmail.com>
@jgmelber jgmelber enabled auto-merge July 13, 2026 17:35
@jgmelber jgmelber added this pull request to the merge queue Jul 13, 2026
Merged via the queue into main with commit 27433d6 Jul 13, 2026
65 checks passed
@jgmelber jgmelber deleted the fix-bootgen-pie branch July 13, 2026 19:26
jgmelber added a commit that referenced this pull request Jul 13, 2026
…e CMake property

Same fix as #3333 (against main), carried forward here since this branch
replaces bootgen's CMakeLists.txt with the 2026.1 upstream-source layout.

The POSITION_INDEPENDENT_CODE property set on bootgen-lib/bootgen doesn't
actually force PIE: this project never calls check_pie_supported(), which
CMake's CMP0083 needs to turn that property into real -fPIE/-pie flags for
an executable target. Confirmed via readelf + strace that the wheel built
from #3327's own commit (main's earlier attempt at this) still ships a
non-PIE `bootgen` and segfaults (SIGSEGV/SEGV_ACCERR jumping into its own
non-executable DYNAMIC segment) once auditwheel repair patches in an RPATH
for vendored OpenSSL -- manylinux_2_28's gcc-toolset doesn't default to
PIE the way a distro's system gcc does.

Pass -fPIC/-fPIE/-pie explicitly, last, so they win over any inherited
-fno-pie/-fno-PIC via ordinary last-flag-wins compiler semantics. Verified
locally under a forced -fno-pie -fno-PIC -no-pie global configuration that
this reliably produces a true PIE (ET_DYN) bootgen, unlike the
property-only approach.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants