Change:
determines which executables it should patch via: However, PIEs have a type of , as in: Questions: Should also patch PIEs? An alternative is to just call manually, but I'm having trouble finding out how to run it in the correct phase. Is there even a reliable way to distinguish between shared libraries and PIEs? I know in general, shared libs don't have an section, but is this a reliable enough assumption? cc
Actually, executables can also be shared libraries at the same time (eg. and I'm doing exactly that in my as well), so the only thing that distinguishes them is an section (except if statically linked of course). So I guess it's a better idea to just look for in instead of what we currently do. At least if I don't miss something, this should be the most reliable way, after all what we want to do with executables is to patch the section. If nobody else sends a PR in the meantime, I'm going to fix this next week. As for it's a bit more difficult, because it needs to be run after the normal hook, so it might be necessary to add .

Discussion:
addEnvHooks "$targetOffset" gatherLibraries isExecutable() { <del> [ "$(file -b -N --mime-type "$1")" = application/x-executable ] } findElfs() { find "$1" -type f -exec "$SHELL" -c ' while [ -n "$1" ]; do mimeType="$(file -b -N --mime-type "$1")" if [ "$mimeType" = application/x-executable  -o "$mimeType" = application/x-pie-executable  -o "$mimeType" = application/x-sharedlib ]; then echo "$1" fi shift done ' -- {} + </del> <ins> # For dynamically linked ELF files it would be enough to check just for the # INTERP section. However, we won't catch statically linked executables as # they only have an ELF type of EXEC but no INTERP. # # So what we do here is just check whether *either* the ELF type is EXEC # *or* there is an INTERP section. This also catches position-independent # executables, as they typically have an INTERP section but their ELF type # is DYN. LANG=C readelf -h -l "$1" 2> /dev/null  | grep -q '^ *Type: *EXEC>|^ *INTERP>' </ins> } # We cache dependencies so that we don't need to search through all of them on

fi } <ins> # Can be used to manually add additional directories with shared object files # to be included for the next autoPatchelf invocation. addAutoPatchelfSearchPath() { local -a findOpts=() # XXX: Somewhat similar to the one in the autoPatchelf function, maybe make #      it DRY someday... while [ $# -gt 0 ]; do case "$1" in --) shift; break;; --no-recurse) shift; findOpts+=("-maxdepth" 1);; --*) echo "addAutoPatchelfSearchPath: ERROR: Invalid command line"  "argument: $1" >&2 return 1;; *) break;; esac done cachedDependencies+=( $(find "$@" "${findOpts[@]}" ! -type d  ( -name '*.so' -o -name '*.so.*' )) ) } </ins> autoPatchelf() { <ins> local norecurse= while [ $# -gt 0 ]; do case "$1" in --) shift; break;; --no-recurse) shift; norecurse=1;; --*) echo "autoPatchelf: ERROR: Invalid command line"  "argument: $1" >&2 return 1;; *) break;; esac done if [ $# -eq 0 ]; then echo "autoPatchelf: No paths to patch specified." >&2 return 1 fi </ins> echo "automatically fixing dependencies for ELF files" >&2 # Add all shared objects of the current output path to the start of # cachedDependencies so that it's choosen first in findDependency. <del> cachedDependencies+=( $(find "$prefix" ! -type d ( -name '*.so' -o -name '*.so.*' )) ) local elffile </del> <ins> addAutoPatchelfSearchPath ${norecurse:+--no-recurse} -- "$@" </ins> # Here we actually have a subshell, which also means that # $cachedDependencies is final at this point, so whenever we want to run # findDependency outside of this, the dependency cache needs to be rebuilt # from scratch, so keep this in mind if you want to run findDependency # outside of this function. <del> findElfs "$prefix" | while read -r elffile; do autoPatchelfFile "$elffile" done </del> <ins> while IFS= read -r -d $'0' file; do isELF "$file" || continue segmentHeaders="$(LANG=C readelf -l "$file")" # Skip if the ELF file doesn't have segment headers (eg. object files). echo "$segmentHeaders" | grep -q '^Program Headers:' || continue if isExecutable "$file"; then # Skip if the executable is statically linked. echo "$segmentHeaders" | grep -q "^ *INTERP>" || continue fi autoPatchelfFile "$file" done < <(find "$@" ${norecurse:+-maxdepth 1} -type f -print0) </ins> } # XXX: This should ultimately use fixupOutputHooks but we currently don't have

# So what we do here is basically run in postFixup and emulate the same # behaviour as fixupOutputHooks because the setup hook for patchelf is run in # fixupOutput and the postFixup hook runs later. <del> postFixupHooks+=( 'for output in $outputs; do prefix="${!output}" autoPatchelf; done' ) </del> <ins> postFixupHooks+=(' if [ -z "$dontAutoPatchelf" ]; then autoPatchelf -- $(for output in $outputs; do [ -e "${!output}" ] || continue echo "${!output}" done) fi ') </ins>

{ deps = [ autoconf264 automake111x gettext libtool ]; } ../build-support/setup-hooks/autoreconf.sh; <del> autoPatchelfHook = makeSetupHook { name = "auto-patchelf-hook"; deps = [ file ]; } </del> <ins> autoPatchelfHook = makeSetupHook { name = "auto-patchelf-hook"; } </ins> ../build-support/setup-hooks/auto-patchelf.sh; ensureNewerSourcesHook = { year }: makeSetupHook {}