Skip to content

Spike: unify name salting behind a single SaltMap#1

Merged
asinghvi17 merged 4 commits into
as/linux-no-patchelffrom
as/salt-remap-spike
May 30, 2026
Merged

Spike: unify name salting behind a single SaltMap#1
asinghvi17 merged 4 commits into
as/linux-no-patchelffrom
as/salt-remap-spike

Conversation

@asinghvi17

Copy link
Copy Markdown
Owner

Spike / for discussion — stacked on as/linux-no-patchelf (PR JuliaLang#150). Targets that branch, not main, so the diff shows only the salting change.

This addresses the review comment on JuliaLang#150 that the salting conventions are messy — the mix of plat_salted_basename (full-basename transform), replace_dep_libs's prepend/prefix convention (implicitly required to match), and the hooks taking the raw salt alongside already-salted inputs.

Approach

Build one explicit name→salted-name description once per run and thread it everywhere, so the salted form of a name is derived in exactly one place:

struct SaltMap{F}
    salt::String                      # retained only as a per-run record (logging)
    rename::F                         # the one definition of "how a name is salted"
    basenames::Dict{String,String}    # original ⇒ salted, for files found on disk
end
  • rename is the platform's transform; it's total (works on basenames, bare SONAME/NEEDED strings, and the extension-less dep_libs stems).
  • basenames records which names were salted, for dependency/NEEDED rewrites and symlink retargeting.
  • They're consistent by construction (basenames[k] == rename(k)).

What this removes

  • plat_salted_basename → folded into plat_make_renamer (the sole salting definition).
  • replace_dep_libs's prepend::Bool + prefix coupling → deleted; salt_dep_libs tokenizes the blob and applies rename per stem (verified byte-identical to the old whole-blob replace on both platforms).
  • Raw salt + already-salted inputs in the rewrite hooksplat_set_library_id! takes the SaltMap and resolves its own id; plat_install_name_change! takes fully-resolved old/new. plat_dep_prefix collapses into a single plat_dep_ref(platform, name).

Also deleted: plat_dep_libs_prepend. macOS vs Linux now differ only in how the map is built — macOS prepends (<salt>_libjulia, may grow, @rpath/<name>), Linux substitutes a same-length token (libjulia<salt>, length-preserving, bare <name>).

Validation

  • test/elf_ops.jl: 47/47, including the synthetic testset (30 assertions) that drives privatize_libjulia_common! end-to-end against the real libjulia.so/libjulia-internal.so and asserts no library keeps an unsalted SONAME/DT_NEEDED.
  • macOS is preserved by construction but not run (no macOS host) — the one spot to eyeball is the @rpath/basename(salted_path) id-set.

🤖 Generated with Claude Code

asinghvi17 and others added 3 commits May 29, 2026 23:47
Replace the three coexisting name-rewriting conventions in the common
privatization logic with one explicit, per-run name map (`SaltMap`) that is
built once by the platform and threaded through every rewrite site.

Previously the salted form of a library name was derived in several places
with conventions that had to match implicitly:

- a full-basename transform hook (`plat_salted_basename`),
- a separate prepend/substitute reconstruction inside the `dep_libs` rewrite
  (the `prepend::Bool` + prefix convention), and
- library-id / dependency-rewrite hooks that took the raw `salt` and re-derived
  the salted form from it (plus a `plat_dep_prefix` string convention).

Now a `SaltMap` carries the platform's name-salting function (`rename`) and a
materialized `original_basename => salted_basename` map for the files actually
found on disk. `rename` is the single definition of "how a name is salted" and
is applied uniformly to basenames, SONAME/install-id strings, dependency
references, and the `dep_libs` stems. The map records "which names were salted"
for dependency/NEEDED rewrites and symlink retargeting.

The only remaining platform difference is how the map is built:
- one platform's renamer prepends a token (may grow; tooling can rewrite
  longer strings),
- the other's renamer substitutes an equal-length token, keeping every
  in-place patch length-preserving.
Dependency-reference framing differs only via a single `plat_dep_ref` hook.

Removed: `plat_salted_basename`, `plat_dep_prefix`, `plat_dep_libs_prepend`,
the `prepend`/prefix coupling in the `dep_libs` rewrite, and the raw-`salt`
arguments on the library-id and dependency-rewrite hooks. Library-id setting
and dependency rewrites now receive only fully-resolved names (or the map).

Behavior is preserved on both platforms by construction; the `dep_libs` rewrite
produces byte-identical output to the prior whole-blob replace. Symbol-version
stamping and symlink handling are unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Make SaltMap{F} carry a concrete renamer type instead of an abstract
`::Function` field, so the salting transform is type-stable. The single
constructor infers F; all SaltMap type annotations are the UnionAll and are
unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
replacements_for pointed each rewritten dependency at the recorded real-file
basename (e.g. the 3-component libjulia.so.1.12.6), but DT_NEEDED / soname
strings are 2-component (libjulia.so.1.12), so on a real build the rewrite grew
the string and the in-place patcher rejected it. Salt the live dependency
string itself instead — matching the salted symlink we already create and
staying length-preserving on Linux; basenames is now only the bundled-or-not
guard. Caught by the full programatic.jl suite (real PackageCompiler build).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@asinghvi17
asinghvi17 force-pushed the as/salt-remap-spike branch from 2194229 to 9a2fad5 Compare May 29, 2026 23:48
Collapse the wrapped # comment blocks in the privatization sources to one line
each. Docstrings are left intact. No behavior change.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@asinghvi17
asinghvi17 marked this pull request as ready for review May 30, 2026 00:09
@asinghvi17
asinghvi17 merged commit dbb2b2e into as/linux-no-patchelf May 30, 2026
12 checks passed
@asinghvi17
asinghvi17 deleted the as/salt-remap-spike branch May 30, 2026 00:09
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