Skip to content

fusion: don't let a broken llvm-nm silently drop the symbol prefix#137

Open
atassis wants to merge 1 commit into
amd:develfrom
atassis:fix/fusion-prefix-symbols-broken-nm
Open

fusion: don't let a broken llvm-nm silently drop the symbol prefix#137
atassis wants to merge 1 commit into
amd:develfrom
atassis:fix/fusion-prefix-symbols-broken-nm

Conversation

@atassis

@atassis atassis commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Summary

KernelCompilationRule._prefix_symbols builds a redefine-syms map with
nm --defined-only --extern-only obj | awk '...' > map and applies it with
objcopy --redefine-syms=map. If nm fails, the map comes out empty, objcopy renames nothing, and every
fused kernel object keeps its bare symbol, which surfaces only much later as undefined symbol: <prefix><sym>
at the per-core link. Two things make that failure silent:

  1. _find_tool returns the first existing llvm-nm / llvm-objcopy even if that binary cannot actually
    run (for example one with an unsatisfied shared-library dependency).
  2. In nm | awk > map the pipeline's exit status is awk's, so a failure of nm is masked.

Fix

  • Add _find_working_tool, which probes each candidate with --version and skips a present-but-unrunnable
    binary, falling through to the system PATH copy and finally to _find_tool (so the existing not-found
    error is preserved). _prefix_symbols and _rename_symbols use it to select llvm-nm / llvm-objcopy.
  • Run nm to a file joined to awk with &&, so a failing nm aborts the build loudly instead of
    yielding an empty map.

Both changes are no-ops when the tools work: the same binary is selected and the same map is produced.

Testing

Reproduced the original silent failure by selecting an llvm-nm that exits nonzero; before the change the
fused link failed with undefined symbol: <prefix><sym>, and after it the build either succeeds (a working
nm is found on PATH) or aborts at the map step with nm's own error, instead of failing opaquely at link
time. No behavior change when nm / objcopy run normally.

KernelCompilationRule._prefix_symbols renames each fused kernel object's
symbols with `nm --defined-only --extern-only obj | awk '...' > map` and then
`objcopy --redefine-syms=map`. Two things combine into a silent failure.

First, _find_tool returns the first existing llvm-nm/llvm-objcopy even if that
binary cannot actually run, for example one with an unsatisfied shared library
dependency. Second, in `nm | awk > map` the pipeline's exit status is awk's, so
a failure of nm is masked: the map comes out empty, objcopy renames nothing,
and every fused object keeps its bare symbol, which surfaces only much later as
`undefined symbol: <prefix><sym>` at the per-core link.

This fixes both. It adds _find_working_tool, which probes each candidate with
`--version` and skips a present-but-unrunnable binary, falling through to the
system PATH copy (and finally to _find_tool, so the existing not-found error is
preserved). And it runs nm to a file joined to awk with `&&`, so a failing nm
aborts the build loudly instead of yielding an empty map. Both changes are
no-ops when the tools work.
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.

1 participant