Skip to content

Commit

Permalink
autoPatchelfHook: add keep_libc flag (#332617)
Browse files Browse the repository at this point in the history
* autoPatchelfHook: add keep_libc flag

- Add keep_libc flag to disable the default libc handling. Intended
  to be used by systemd.
- Add autoPatchelfFlags to autoPatchelfHook for passing arguments to
  the autoPatchelf script

This reverts part of the change made in #307068 / 80be926.

Fixes #332533
  • Loading branch information
squalus authored Aug 14, 2024
1 parent 1582d76 commit 0a3ed67
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 6 deletions.
30 changes: 24 additions & 6 deletions pkgs/build-support/setup-hooks/auto-patchelf.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ class Dependency:
found: bool = False # Whether it was found somewhere


def auto_patchelf_file(path: Path, runtime_deps: list[Path], append_rpaths: list[Path] = [], extra_args: list[str] = []) -> list[Dependency]:
def auto_patchelf_file(path: Path, runtime_deps: list[Path], append_rpaths: list[Path] = [], keep_libc: bool = False, extra_args: list[str] = []) -> list[Dependency]:
try:
with open_elf(path) as elf:

Expand Down Expand Up @@ -257,26 +257,36 @@ def auto_patchelf_file(path: Path, runtime_deps: list[Path], append_rpaths: list
# 1. If a candidate is an absolute path, it is already a
# valid dependency if that path exists, and nothing needs
# to be done. It should be an error if that path does not exist.
# 2. If a candidate is found in our library dependencies, that
# 2. If a candidate is found within libc, it should be dropped
# and resolved automatically by the dynamic linker, unless
# keep_libc is enabled.
# 3. If a candidate is found in our library dependencies, that
# dependency should be added to rpath.
# 3. If a candidate is found in libc, it will be correctly
# resolved by the dynamic linker automatically.
# 4. If all of the above fail, libc dependencies should still be
# considered found. This is in contrast to step 2, because
# enabling keep_libc should allow libc to be found in step 3
# if possible to preserve its presence in rpath.
#
# These conditions are checked in this order, because #2
# and #3 may both be true. In that case, we still want to
# add the dependency to rpath, as the original binary
# presumably had it and this should be preserved.

is_libc = (libc_lib / candidate).is_file()

if candidate.is_absolute() and candidate.is_file():
was_found = True
break
elif is_libc and not keep_libc:
was_found = True
break
elif found_dependency := find_dependency(candidate.name, file_arch, file_osabi):
rpath.append(found_dependency)
dependencies.append(Dependency(path, candidate, found=True))
print(f" {candidate} -> found: {found_dependency}")
was_found = True
break
elif (libc_lib / candidate).is_file():
elif is_libc and keep_libc:
was_found = True
break

Expand Down Expand Up @@ -306,6 +316,7 @@ def auto_patchelf(
recursive: bool = True,
ignore_missing: list[str] = [],
append_rpaths: list[Path] = [],
keep_libc: bool = False,
extra_args: list[str] = []) -> None:

if not paths_to_patch:
Expand All @@ -319,7 +330,7 @@ def auto_patchelf(
dependencies = []
for path in chain.from_iterable(glob(p, '*', recursive) for p in paths_to_patch):
if not path.is_symlink() and path.is_file():
dependencies += auto_patchelf_file(path, runtime_deps, append_rpaths, extra_args)
dependencies += auto_patchelf_file(path, runtime_deps, append_rpaths, keep_libc, extra_args)

missing = [dep for dep in dependencies if not dep.found]

Expand Down Expand Up @@ -377,6 +388,12 @@ def main() -> None:
type=Path,
help="Paths to append to all runtime paths unconditionally",
)
parser.add_argument(
"--keep-libc",
dest="keep_libc",
action="store_true",
help="Attempt to search for and relink libc dependencies.",
)
parser.add_argument(
"--extra-args",
# Undocumented Python argparse feature: consume all remaining arguments
Expand All @@ -398,6 +415,7 @@ def main() -> None:
args.recursive,
args.ignore_missing,
append_rpaths=args.append_rpaths,
keep_libc=args.keep_libc,
extra_args=args.extra_args)


Expand Down
3 changes: 3 additions & 0 deletions pkgs/build-support/setup-hooks/auto-patchelf.sh
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,13 @@ autoPatchelf() {
local appendRunpathsArray=( "${appendRunpaths[@]}" )
local runtimeDependenciesArray=( "${runtimeDependencies[@]}" )
local patchelfFlagsArray=( "${patchelfFlags[@]}" )
local autoPatchelfFlagsArray=( "${autoPatchelfFlags[@]}" )
else
readarray -td' ' ignoreMissingDepsArray < <(echo -n "$autoPatchelfIgnoreMissingDeps")
local appendRunpathsArray=($appendRunpaths)
local runtimeDependenciesArray=($runtimeDependencies)
local patchelfFlagsArray=($patchelfFlags)
local autoPatchelfFlagsArray=($autoPatchelfFlags)
fi

# Check if ignoreMissingDepsArray contains "1" and if so, replace it with
Expand All @@ -85,6 +87,7 @@ autoPatchelf() {
"${extraAutoPatchelfLibs[@]}" \
--runtime-dependencies "${runtimeDependenciesArray[@]/%//lib}" \
--append-rpaths "${appendRunpathsArray[@]}" \
"${autoPatchelfFlagsArray[@]}" \
--extra-args "${patchelfFlagsArray[@]}"
}

Expand Down
2 changes: 2 additions & 0 deletions pkgs/os-specific/linux/systemd/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,8 @@ stdenv.mkDerivation (finalAttrs: {
]
;

autoPatchelfFlags = [ "--keep-libc" ];

buildInputs =
[
libxcrypt
Expand Down

0 comments on commit 0a3ed67

Please sign in to comment.