nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
1# shellcheck shell=bash
2
3# getRunpathEntries
4# Append the runpath entries of the dynamically linked ELF file at path to the indexed array referenced by
5# outputArrRef.
6#
7# NOTE: This function does not check if path is a valid ELF file.
8#
9# Arguments:
10# - path: a path to an ELF file with a dynamic section
11# - outputArrRef: a reference to an indexed array (mutated only by appending)
12#
13# Returns 0 if the file is dynamically linked and the runpath was appended to the output array.
14# Returns 1 if patchelf fails (e.g., the ELF file is not dynamically linked, so patchelf fails to print the rpath).
15getRunpathEntries() {
16 if (($# != 2)); then
17 nixErrorLog "expected two arguments!"
18 nixErrorLog "usage: getRunpathEntries path outputArrRef"
19 exit 1
20 fi
21
22 local -r path="$1"
23 local -rn outputArrRef="$2"
24
25 if [[ ! -f $path ]]; then
26 nixErrorLog "first argument path $path is not a file"
27 exit 1
28 elif ! isDeclaredArray "${!outputArrRef}"; then
29 nixErrorLog "second argument outputArrRef must be a reference to an indexed array"
30 exit 1
31 fi
32
33 # Declare runpath separately to avoid masking the return value of patchelf.
34 local runpath
35 # Files that are not dynamically linked cause patchelf to exit with a non-zero status and print to stderr.
36 # If patchelf fails to print the rpath, we assume the file is not dynamically linked.
37 runpath="$(patchelf --print-rpath "$path" 2>/dev/null)" || return 1
38
39 # If the runpath is empty and we feed it to mapfile, it gives us a singleton array with an empty string.
40 # We want to avoid that, so we check if the runpath is empty before trying to populate runpathEntries.
41 local -a runpathEntries=()
42 if [[ -n $runpath ]]; then
43 mapfile -d ':' -t runpathEntries < <(echo -n "$runpath")
44 fi
45
46 outputArrRef+=("${runpathEntries[@]}")
47
48 return 0
49}