kumquat-buildroot/support/scripts/fix-rpath

182 lines
5.8 KiB
Plaintext
Raw Normal View History

#!/usr/bin/env bash
# Copyright (C) 2016 Samuel Martin <s.martin49@gmail.com>
# Copyright (C) 2017 Wolfgang Grandegger <wg@grandegger.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
usage() {
cat <<EOF >&2
Usage: ${0} TREE_KIND
Description:
This script scans a tree and sanitize ELF files' RPATH found in there.
Sanitization behaves the same whatever the kind of the processed tree,
but the resulting RPATH differs. The rpath sanitization is done using
"patchelf --make-rpath-relative".
Arguments:
TREE_KIND Kind of tree to be processed.
Allowed values: host, target, staging
Environment:
PATCHELF patchelf program to use
(default: HOST_DIR/bin/patchelf)
HOST_DIR host directory
STAGING_DIR staging directory
TARGET_DIR target directory
TOOLCHAIN_EXTERNAL_DOWNLOAD_INSTALL_DIR
(default HOST_DIR/opt/ext-toolchain)
PARALLEL_JOBS number of parallel jobs to run
Returns: 0 if success or 1 in case of error
EOF
}
support/scripts: fix fix-rpath Commit 134900401f08 (support/scripts/fix-rpath: parallelize patching files) broke the rpath fixup, because it improperly quoted or expanded variables: - $@ was expanded in the main() context, rather than in the sub-bash as expected, propagating incorrect parameters to patch_file(); - an array was passed without array expansion, so only the first item was passed; that was in turn assigned to a string, anyway loosign the array. Liuckily, we only ever put a single item in that array, so that worked by chance. We fix that by inverting the parameters to patch_elf(), where the extra args are passed last, so we can put as many we want in the future. We also pass every variables as positional parameters outside the bash -c command, which allows us proper quoting of all variables, specifically of the extra args array which now comes last. The ultralong line was split, too, in a hopefully easier-to-read form. Fixing all that also required fixing the many shellcheck issues at the same time (wome were pre-existing before 134900401f08). While at it, expand two TABs into spaces like the rest of the script. Note: shellcheck does not seem to warn when a variable expansion will be used as the command to run, i.e. ${PATCHELF} does not trigger the quoting error. Still, for consistency, we also double-quote it (we know it is a single word, as it is already double-quoted once in the script). Fixes: 134900401f08 Cc: Victor Dumas <dumasv.dev@gmail.com> Signed-off-by: Yann E. MORIN <yann.morin.1998@free.fr>
2023-08-07 23:04:10 +02:00
: "${PATCHELF:=${HOST_DIR}/bin/patchelf}"
# ELF files should not be in these sub-directories
HOST_EXCLUDEPATHS="/share/terminfo"
STAGING_EXCLUDEPATHS="/usr/include /usr/share/terminfo"
TARGET_EXCLUDEPATHS="/lib/firmware"
patch_file() {
support/scripts: fix fix-rpath Commit 134900401f08 (support/scripts/fix-rpath: parallelize patching files) broke the rpath fixup, because it improperly quoted or expanded variables: - $@ was expanded in the main() context, rather than in the sub-bash as expected, propagating incorrect parameters to patch_file(); - an array was passed without array expansion, so only the first item was passed; that was in turn assigned to a string, anyway loosign the array. Liuckily, we only ever put a single item in that array, so that worked by chance. We fix that by inverting the parameters to patch_elf(), where the extra args are passed last, so we can put as many we want in the future. We also pass every variables as positional parameters outside the bash -c command, which allows us proper quoting of all variables, specifically of the extra args array which now comes last. The ultralong line was split, too, in a hopefully easier-to-read form. Fixing all that also required fixing the many shellcheck issues at the same time (wome were pre-existing before 134900401f08). While at it, expand two TABs into spaces like the rest of the script. Note: shellcheck does not seem to warn when a variable expansion will be used as the command to run, i.e. ${PATCHELF} does not trigger the quoting error. Still, for consistency, we also double-quote it (we know it is a single word, as it is already double-quoted once in the script). Fixes: 134900401f08 Cc: Victor Dumas <dumasv.dev@gmail.com> Signed-off-by: Yann E. MORIN <yann.morin.1998@free.fr>
2023-08-07 23:04:10 +02:00
local PATCHELF rootdir file
local -a sanitize_extra_args
PATCHELF="${1}"
rootdir="${2}"
support/scripts: fix fix-rpath Commit 134900401f08 (support/scripts/fix-rpath: parallelize patching files) broke the rpath fixup, because it improperly quoted or expanded variables: - $@ was expanded in the main() context, rather than in the sub-bash as expected, propagating incorrect parameters to patch_file(); - an array was passed without array expansion, so only the first item was passed; that was in turn assigned to a string, anyway loosign the array. Liuckily, we only ever put a single item in that array, so that worked by chance. We fix that by inverting the parameters to patch_elf(), where the extra args are passed last, so we can put as many we want in the future. We also pass every variables as positional parameters outside the bash -c command, which allows us proper quoting of all variables, specifically of the extra args array which now comes last. The ultralong line was split, too, in a hopefully easier-to-read form. Fixing all that also required fixing the many shellcheck issues at the same time (wome were pre-existing before 134900401f08). While at it, expand two TABs into spaces like the rest of the script. Note: shellcheck does not seem to warn when a variable expansion will be used as the command to run, i.e. ${PATCHELF} does not trigger the quoting error. Still, for consistency, we also double-quote it (we know it is a single word, as it is already double-quoted once in the script). Fixes: 134900401f08 Cc: Victor Dumas <dumasv.dev@gmail.com> Signed-off-by: Yann E. MORIN <yann.morin.1998@free.fr>
2023-08-07 23:04:10 +02:00
file="${3}"
shift 3
sanitize_extra_args=("${@}")
# check if it's an ELF file
support/scripts: fix fix-rpath Commit 134900401f08 (support/scripts/fix-rpath: parallelize patching files) broke the rpath fixup, because it improperly quoted or expanded variables: - $@ was expanded in the main() context, rather than in the sub-bash as expected, propagating incorrect parameters to patch_file(); - an array was passed without array expansion, so only the first item was passed; that was in turn assigned to a string, anyway loosign the array. Liuckily, we only ever put a single item in that array, so that worked by chance. We fix that by inverting the parameters to patch_elf(), where the extra args are passed last, so we can put as many we want in the future. We also pass every variables as positional parameters outside the bash -c command, which allows us proper quoting of all variables, specifically of the extra args array which now comes last. The ultralong line was split, too, in a hopefully easier-to-read form. Fixing all that also required fixing the many shellcheck issues at the same time (wome were pre-existing before 134900401f08). While at it, expand two TABs into spaces like the rest of the script. Note: shellcheck does not seem to warn when a variable expansion will be used as the command to run, i.e. ${PATCHELF} does not trigger the quoting error. Still, for consistency, we also double-quote it (we know it is a single word, as it is already double-quoted once in the script). Fixes: 134900401f08 Cc: Victor Dumas <dumasv.dev@gmail.com> Signed-off-by: Yann E. MORIN <yann.morin.1998@free.fr>
2023-08-07 23:04:10 +02:00
rpath="$("${PATCHELF}" --print-rpath "${file}" 2>&1)"
if test $? -ne 0 ; then
return 0
fi
# make files writable if necessary
support/scripts: fix fix-rpath Commit 134900401f08 (support/scripts/fix-rpath: parallelize patching files) broke the rpath fixup, because it improperly quoted or expanded variables: - $@ was expanded in the main() context, rather than in the sub-bash as expected, propagating incorrect parameters to patch_file(); - an array was passed without array expansion, so only the first item was passed; that was in turn assigned to a string, anyway loosign the array. Liuckily, we only ever put a single item in that array, so that worked by chance. We fix that by inverting the parameters to patch_elf(), where the extra args are passed last, so we can put as many we want in the future. We also pass every variables as positional parameters outside the bash -c command, which allows us proper quoting of all variables, specifically of the extra args array which now comes last. The ultralong line was split, too, in a hopefully easier-to-read form. Fixing all that also required fixing the many shellcheck issues at the same time (wome were pre-existing before 134900401f08). While at it, expand two TABs into spaces like the rest of the script. Note: shellcheck does not seem to warn when a variable expansion will be used as the command to run, i.e. ${PATCHELF} does not trigger the quoting error. Still, for consistency, we also double-quote it (we know it is a single word, as it is already double-quoted once in the script). Fixes: 134900401f08 Cc: Victor Dumas <dumasv.dev@gmail.com> Signed-off-by: Yann E. MORIN <yann.morin.1998@free.fr>
2023-08-07 23:04:10 +02:00
changed="$(chmod -c u+w "${file}")"
# With per-package directory support, most RPATH of host
# binaries will point to per-package directories. This won't
# work with the --make-rpath-relative ${rootdir} invocation as
# the per-package host directory is not within ${rootdir}. So,
# we rewrite all RPATHs pointing to per-package directories so
# that they point to the global host directry.
support/scripts: fix fix-rpath Commit 134900401f08 (support/scripts/fix-rpath: parallelize patching files) broke the rpath fixup, because it improperly quoted or expanded variables: - $@ was expanded in the main() context, rather than in the sub-bash as expected, propagating incorrect parameters to patch_file(); - an array was passed without array expansion, so only the first item was passed; that was in turn assigned to a string, anyway loosign the array. Liuckily, we only ever put a single item in that array, so that worked by chance. We fix that by inverting the parameters to patch_elf(), where the extra args are passed last, so we can put as many we want in the future. We also pass every variables as positional parameters outside the bash -c command, which allows us proper quoting of all variables, specifically of the extra args array which now comes last. The ultralong line was split, too, in a hopefully easier-to-read form. Fixing all that also required fixing the many shellcheck issues at the same time (wome were pre-existing before 134900401f08). While at it, expand two TABs into spaces like the rest of the script. Note: shellcheck does not seem to warn when a variable expansion will be used as the command to run, i.e. ${PATCHELF} does not trigger the quoting error. Still, for consistency, we also double-quote it (we know it is a single word, as it is already double-quoted once in the script). Fixes: 134900401f08 Cc: Victor Dumas <dumasv.dev@gmail.com> Signed-off-by: Yann E. MORIN <yann.morin.1998@free.fr>
2023-08-07 23:04:10 +02:00
# shellcheck disable=SC2001 # ${var//search/replace} hard when search or replace have / in them
changed_rpath="$(echo "${rpath}" | sed "s@${PER_PACKAGE_DIR}/[^/]\+/host@${HOST_DIR}@")"
if test "${rpath}" != "${changed_rpath}" ; then
support/scripts: fix fix-rpath Commit 134900401f08 (support/scripts/fix-rpath: parallelize patching files) broke the rpath fixup, because it improperly quoted or expanded variables: - $@ was expanded in the main() context, rather than in the sub-bash as expected, propagating incorrect parameters to patch_file(); - an array was passed without array expansion, so only the first item was passed; that was in turn assigned to a string, anyway loosign the array. Liuckily, we only ever put a single item in that array, so that worked by chance. We fix that by inverting the parameters to patch_elf(), where the extra args are passed last, so we can put as many we want in the future. We also pass every variables as positional parameters outside the bash -c command, which allows us proper quoting of all variables, specifically of the extra args array which now comes last. The ultralong line was split, too, in a hopefully easier-to-read form. Fixing all that also required fixing the many shellcheck issues at the same time (wome were pre-existing before 134900401f08). While at it, expand two TABs into spaces like the rest of the script. Note: shellcheck does not seem to warn when a variable expansion will be used as the command to run, i.e. ${PATCHELF} does not trigger the quoting error. Still, for consistency, we also double-quote it (we know it is a single word, as it is already double-quoted once in the script). Fixes: 134900401f08 Cc: Victor Dumas <dumasv.dev@gmail.com> Signed-off-by: Yann E. MORIN <yann.morin.1998@free.fr>
2023-08-07 23:04:10 +02:00
"${PATCHELF}" --set-rpath "${changed_rpath}" "${file}"
fi
# call patchelf to sanitize the rpath
support/scripts: fix fix-rpath Commit 134900401f08 (support/scripts/fix-rpath: parallelize patching files) broke the rpath fixup, because it improperly quoted or expanded variables: - $@ was expanded in the main() context, rather than in the sub-bash as expected, propagating incorrect parameters to patch_file(); - an array was passed without array expansion, so only the first item was passed; that was in turn assigned to a string, anyway loosign the array. Liuckily, we only ever put a single item in that array, so that worked by chance. We fix that by inverting the parameters to patch_elf(), where the extra args are passed last, so we can put as many we want in the future. We also pass every variables as positional parameters outside the bash -c command, which allows us proper quoting of all variables, specifically of the extra args array which now comes last. The ultralong line was split, too, in a hopefully easier-to-read form. Fixing all that also required fixing the many shellcheck issues at the same time (wome were pre-existing before 134900401f08). While at it, expand two TABs into spaces like the rest of the script. Note: shellcheck does not seem to warn when a variable expansion will be used as the command to run, i.e. ${PATCHELF} does not trigger the quoting error. Still, for consistency, we also double-quote it (we know it is a single word, as it is already double-quoted once in the script). Fixes: 134900401f08 Cc: Victor Dumas <dumasv.dev@gmail.com> Signed-off-by: Yann E. MORIN <yann.morin.1998@free.fr>
2023-08-07 23:04:10 +02:00
"${PATCHELF}" --make-rpath-relative "${rootdir}" "${sanitize_extra_args[@]}" "${file}"
# restore the original permission
test "${changed}" != "" && chmod u-w "${file}"
}
main() {
support/scripts: fix fix-rpath Commit 134900401f08 (support/scripts/fix-rpath: parallelize patching files) broke the rpath fixup, because it improperly quoted or expanded variables: - $@ was expanded in the main() context, rather than in the sub-bash as expected, propagating incorrect parameters to patch_file(); - an array was passed without array expansion, so only the first item was passed; that was in turn assigned to a string, anyway loosign the array. Liuckily, we only ever put a single item in that array, so that worked by chance. We fix that by inverting the parameters to patch_elf(), where the extra args are passed last, so we can put as many we want in the future. We also pass every variables as positional parameters outside the bash -c command, which allows us proper quoting of all variables, specifically of the extra args array which now comes last. The ultralong line was split, too, in a hopefully easier-to-read form. Fixing all that also required fixing the many shellcheck issues at the same time (wome were pre-existing before 134900401f08). While at it, expand two TABs into spaces like the rest of the script. Note: shellcheck does not seem to warn when a variable expansion will be used as the command to run, i.e. ${PATCHELF} does not trigger the quoting error. Still, for consistency, we also double-quote it (we know it is a single word, as it is already double-quoted once in the script). Fixes: 134900401f08 Cc: Victor Dumas <dumasv.dev@gmail.com> Signed-off-by: Yann E. MORIN <yann.morin.1998@free.fr>
2023-08-07 23:04:10 +02:00
local rootdir tree
local -a find_args sanitize_extra_args
tree="${1}"
if ! "${PATCHELF}" --version > /dev/null 2>&1; then
support/scripts: fix fix-rpath Commit 134900401f08 (support/scripts/fix-rpath: parallelize patching files) broke the rpath fixup, because it improperly quoted or expanded variables: - $@ was expanded in the main() context, rather than in the sub-bash as expected, propagating incorrect parameters to patch_file(); - an array was passed without array expansion, so only the first item was passed; that was in turn assigned to a string, anyway loosign the array. Liuckily, we only ever put a single item in that array, so that worked by chance. We fix that by inverting the parameters to patch_elf(), where the extra args are passed last, so we can put as many we want in the future. We also pass every variables as positional parameters outside the bash -c command, which allows us proper quoting of all variables, specifically of the extra args array which now comes last. The ultralong line was split, too, in a hopefully easier-to-read form. Fixing all that also required fixing the many shellcheck issues at the same time (wome were pre-existing before 134900401f08). While at it, expand two TABs into spaces like the rest of the script. Note: shellcheck does not seem to warn when a variable expansion will be used as the command to run, i.e. ${PATCHELF} does not trigger the quoting error. Still, for consistency, we also double-quote it (we know it is a single word, as it is already double-quoted once in the script). Fixes: 134900401f08 Cc: Victor Dumas <dumasv.dev@gmail.com> Signed-off-by: Yann E. MORIN <yann.morin.1998@free.fr>
2023-08-07 23:04:10 +02:00
echo "Error: can't execute patchelf utility '${PATCHELF}'"
exit 1
fi
case "${tree}" in
host)
rootdir="${HOST_DIR}"
# do not process the sysroot (only contains target binaries)
find_args+=( "-path" "${STAGING_DIR}" "-prune" "-o" )
# do not process the external toolchain installation directory to
# avoid breaking it.
test "${TOOLCHAIN_EXTERNAL_DOWNLOAD_INSTALL_DIR}" != "" && \
find_args+=( "-path" "${TOOLCHAIN_EXTERNAL_DOWNLOAD_INSTALL_DIR}" "-prune" "-o" )
for excludepath in ${HOST_EXCLUDEPATHS}; do
find_args+=( "-path" "${HOST_DIR}""${excludepath}" "-prune" "-o" )
done
# do not process the patchelf binary but a copy to work-around "file in use"
find_args+=( "-path" "${PATCHELF}" "-prune" "-o" )
cp "${PATCHELF}" "${PATCHELF}.__to_be_patched"
# we always want $ORIGIN-based rpaths to make it relocatable.
sanitize_extra_args+=( "--relative-to-file" )
;;
staging)
rootdir="${STAGING_DIR}"
# ELF files should not be in these sub-directories
for excludepath in ${STAGING_EXCLUDEPATHS}; do
find_args+=( "-path" "${STAGING_DIR}""${excludepath}" "-prune" "-o" )
done
# should be like for the target tree below
sanitize_extra_args+=( "--no-standard-lib-dirs" )
;;
target)
rootdir="${TARGET_DIR}"
for excludepath in ${TARGET_EXCLUDEPATHS}; do
find_args+=( "-path" "${TARGET_DIR}""${excludepath}" "-prune" "-o" )
done
# we don't want $ORIGIN-based rpaths but absolute paths without rootdir.
# we also want to remove rpaths pointing to /lib or /usr/lib.
sanitize_extra_args+=( "--no-standard-lib-dirs" )
;;
*)
usage
exit 1
;;
esac
find_args+=( "-type" "f" "-print0" )
export -f patch_file
# Limit the number of cores used
support/scripts: fix fix-rpath Commit 134900401f08 (support/scripts/fix-rpath: parallelize patching files) broke the rpath fixup, because it improperly quoted or expanded variables: - $@ was expanded in the main() context, rather than in the sub-bash as expected, propagating incorrect parameters to patch_file(); - an array was passed without array expansion, so only the first item was passed; that was in turn assigned to a string, anyway loosign the array. Liuckily, we only ever put a single item in that array, so that worked by chance. We fix that by inverting the parameters to patch_elf(), where the extra args are passed last, so we can put as many we want in the future. We also pass every variables as positional parameters outside the bash -c command, which allows us proper quoting of all variables, specifically of the extra args array which now comes last. The ultralong line was split, too, in a hopefully easier-to-read form. Fixing all that also required fixing the many shellcheck issues at the same time (wome were pre-existing before 134900401f08). While at it, expand two TABs into spaces like the rest of the script. Note: shellcheck does not seem to warn when a variable expansion will be used as the command to run, i.e. ${PATCHELF} does not trigger the quoting error. Still, for consistency, we also double-quote it (we know it is a single word, as it is already double-quoted once in the script). Fixes: 134900401f08 Cc: Victor Dumas <dumasv.dev@gmail.com> Signed-off-by: Yann E. MORIN <yann.morin.1998@free.fr>
2023-08-07 23:04:10 +02:00
# shellcheck disable=SC2016 # ${@} has to be expanded in the sub-shell.
find "${rootdir}" "${find_args[@]}" \
| xargs -0 -r -P "${PARALLEL_JOBS:-1}" -I {} \
bash -c 'patch_file "${@}"' _ "${PATCHELF}" "${rootdir}" {} "${sanitize_extra_args[@]}"
# Restore patched patchelf utility
test "${tree}" = "host" && mv "${PATCHELF}.__to_be_patched" "${PATCHELF}"
# ignore errors
return 0
}
support/scripts: fix fix-rpath Commit 134900401f08 (support/scripts/fix-rpath: parallelize patching files) broke the rpath fixup, because it improperly quoted or expanded variables: - $@ was expanded in the main() context, rather than in the sub-bash as expected, propagating incorrect parameters to patch_file(); - an array was passed without array expansion, so only the first item was passed; that was in turn assigned to a string, anyway loosign the array. Liuckily, we only ever put a single item in that array, so that worked by chance. We fix that by inverting the parameters to patch_elf(), where the extra args are passed last, so we can put as many we want in the future. We also pass every variables as positional parameters outside the bash -c command, which allows us proper quoting of all variables, specifically of the extra args array which now comes last. The ultralong line was split, too, in a hopefully easier-to-read form. Fixing all that also required fixing the many shellcheck issues at the same time (wome were pre-existing before 134900401f08). While at it, expand two TABs into spaces like the rest of the script. Note: shellcheck does not seem to warn when a variable expansion will be used as the command to run, i.e. ${PATCHELF} does not trigger the quoting error. Still, for consistency, we also double-quote it (we know it is a single word, as it is already double-quoted once in the script). Fixes: 134900401f08 Cc: Victor Dumas <dumasv.dev@gmail.com> Signed-off-by: Yann E. MORIN <yann.morin.1998@free.fr>
2023-08-07 23:04:10 +02:00
main "${@}"