commit:     e7c98eccdac4dc1e5a7de9e4048a37ea3756327d
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Mon Jun  9 17:47:42 2025 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Wed Jun 11 03:26:17 2025 +0000
URL:        https://gitweb.gentoo.org/proj/portage.git/commit/?id=e7c98ecc

estrip: have function declarations precede code

Refrain from interspersing function declarations with code that isn't
function-scoped. Instead, ensure that the function declarations precede
all other commands, with the sole exception of the command that sources
the "isolated-functions.sh" library.

Transform the get_inode_number(), dump_xattrs() and restore_xattrs()
functions into ones that redeclare themselves upon first ever being
called. Doing this helps to keep the code neat and tidy, while also
allowing for the necessary tests to be lazily performed.

See-also: d015284bbdcdd36b5932a882d11fef9bf0941b96
Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 bin/estrip | 458 ++++++++++++++++++++++++++++++++-----------------------------
 1 file changed, 237 insertions(+), 221 deletions(-)

diff --git a/bin/estrip b/bin/estrip
index 1c1af8965a..2dada0577c 100755
--- a/bin/estrip
+++ b/bin/estrip
@@ -5,214 +5,6 @@
 
 source "${PORTAGE_BIN_PATH}"/helper-functions.sh || exit 1
 
-declare -A has_feature
-declare -A has_restriction
-
-for key in compressdebug dedupdebug installsources nostrip splitdebug xattr; do
-       contains_word "$key" "${FEATURES}"
-       has_feature[$key]=$(( $? == 0 ))
-done
-
-for key in binchecks dedupdebug installsources splitdebug strip; do
-       contains_word "$key" "${PORTAGE_RESTRICT}"
-       has_restriction[$key]=$(( $? == 0 ))
-done
-
-if ! ___eapi_has_prefix_variables; then
-       EPREFIX= ED=${D}
-fi
-
-if (( ! has_restriction[strip] && ! has_feature[nostrip] )); then
-       do_banner=1
-       do_skip=0
-elif (( ! has_feature[installsources] )); then
-       exit 0
-else
-       do_banner=0
-       do_skip=1
-fi
-
-do_prepstrip=0
-
-while [[ $# -gt 0 ]] ; do
-       case $1 in
-       --ignore)
-               shift
-
-               skip_dirs=()
-               for skip; do
-                       if [[ -d ${ED%/}/${skip#/} ]]; then
-                               skip_dirs+=( "${ED%/}/${skip#/}" )
-                       else
-                               rm -f "${ED%/}/${skip#/}.estrip" || die
-                       fi
-               done
-
-               if (( ${#skip_dirs[@]} )); then
-                       find "${skip_dirs[@]}" -name '*.estrip' -delete || die
-               fi
-
-               exit 0
-               ;;
-       --queue)
-               shift
-
-               find_paths=()
-               for path; do
-                       if [[ -e ${ED%/}/${path#/} ]]; then
-                               find_paths+=( "${ED%/}/${path#/}" )
-                       fi
-               done
-
-               if (( ${#find_paths[@]} )); then
-                       # We can avoid scanelf calls for binaries we already
-                       # checked in install_qa_check (where we generate
-                       # NEEDED for everything installed).
-                       #
-                       # EAPI 7+ has controlled stripping (dostrip) though
-                       # which is why estrip has the queue/dequeue logic,
-                       # so we need to take the intersection of:
-                       # 1. files scanned earlier (all ELF installed)
-                       #    (note that this should be a superset of 2., so we 
don't
-                       #    need to worry about unknown files appearing)
-                       #
-                       # 2. the files we're interested in right now
-                       scanelf_results=()
-                       if [[ -f "${PORTAGE_BUILDDIR}"/build-info/NEEDED ]] ; 
then
-                               # The arguments may not be exact files 
(probably aren't), but search paths/directories
-                               # which should then be searched recursively.
-                               while IFS= read -r needed_entry ; do
-                                       for find_path in "${find_paths[@]}" ; do
-                                               # NEEDED has a bunch of entries 
like:
-                                               # /usr/lib64/libfoo.so libc.so
-                                               #
-                                               # find_path entries may be 
exact paths (like /usr/lib64/libfoo.so)
-                                               # or instead /usr/lib64, or 
${ED}/usr, etc.
-                                               #
-                                               # We check if the beginning 
(i.e. first entry) of the NEEDED line
-                                               # matches the path given
-                                               # e.g. find_path="/usr/lib64" 
will match needed_entry="/usr/lib64/libfoo.so libc.so".
-                                               
needed_entry_file="${needed_entry% *}"
-                                               if [[ "${needed_entry_file}" =~ 
^${find_path##"${D}"} ]] ; then
-                                                       scanelf_results+=( 
"${D}${needed_entry_file}" )
-                                               fi
-                                       done
-                               done < "${PORTAGE_BUILDDIR}"/build-info/NEEDED
-                       else
-                               mapfile -t scanelf_results < <(scanelf -yqRBF 
'#k%F' -k '.symtab' "${find_paths[@]}")
-                       fi
-
-                       while IFS= read -r path; do
-                               >> "${path}.estrip" || die
-                       done < <(
-                               (( ${#scanelf_results[@]} )) && printf "%s\n" 
"${scanelf_results[@]}"
-                               find "${find_paths[@]}" -type f ! -type l -name 
'*.a'
-                       )
-
-                       unset scanelf_results needed_entry needed_entry_file 
find_path
-               fi
-
-               exit 0
-               ;;
-       --dequeue)
-               [[ $# -eq 1 ]] || die "${0##*/}: $1 takes no additional 
arguments"
-               break
-               ;;
-       --prepallstrip)
-               [[ $# -eq 1 ]] || die "${0##*/}: $1 takes no additional 
arguments"
-               do_prepstrip=1
-               break
-               ;;
-       *)
-               die "${0##*/}: unknown arguments '$*'"
-               exit 1
-               ;;
-       esac
-       shift
-done
-set -- "${ED}"
-
-do_preserve_xattr=0
-if [[ ${KERNEL} == linux ]] && (( has_feature[xattr] )); then
-       do_preserve_xattr=1
-       if type -P getfattr >/dev/null && type -P setfattr >/dev/null ; then
-               dump_xattrs() {
-                       getfattr -d -m - --absolute-names "$1"
-               }
-               restore_xattrs() {
-                       setfattr --restore=-
-               }
-       else
-               dump_xattrs() {
-                       PYTHONPATH=${PORTAGE_PYTHONPATH:-${PORTAGE_PYM_PATH}} \
-                       "${PORTAGE_PYTHON:-/usr/bin/python}" \
-                       "${PORTAGE_BIN_PATH}/xattr-helper.py" --dump < <(echo 
-n "$1")
-               }
-
-               restore_xattrs() {
-                       PYTHONPATH=${PORTAGE_PYTHONPATH:-${PORTAGE_PYM_PATH}} \
-                       "${PORTAGE_PYTHON:-/usr/bin/python}" \
-                       "${PORTAGE_BIN_PATH}/xattr-helper.py" --restore
-               }
-       fi
-fi
-
-# Determine the names of the tools that might subsequently be used. For several
-# of these, their ${CHOST}-prefixed variants are preferred, if found to exist.
-declare -A name_of
-for bin in debugedit dwz {,"${CHOST}-"}{'objcopy','ranlib','readelf','strip'}; 
do
-       key=${bin#"${CHOST}-"}
-       if [[ ! ${name_of[$key]} ]] || hash "${bin}" 2>/dev/null; then
-               name_of[$key]=${bin}
-       fi
-done
-
-# If debugedit does not exist, consider some alternative locations for it.
-if ! hash "${name_of[debugedit]}" 2>/dev/null; then
-       debugedit_paths=(
-               "${EPREFIX}/usr/libexec/rpm/debugedit"
-       )
-       for x in "${debugedit_paths[@]}"; do
-               if [[ -x ${x} ]]; then
-                       name_of[debugedit]=${x}
-                       break
-               fi
-       done
-fi
-
-# Declare a map to keep track of whether warnings in certain categories have
-# been issued for a missing tool.
-declare -A warned_for
-
-# Figure out what tool set we're using to strip stuff
-unset SAFE_STRIP_FLAGS DEF_STRIP_FLAGS SPLIT_STRIP_FLAGS
-case $("${name_of[strip]}" --version 2>/dev/null) in
-       *elfutils*) # dev-libs/elfutils
-               # elfutils default behavior is always safe, so don't need to 
specify
-               # any flags at all
-               SAFE_STRIP_FLAGS=""
-               DEF_STRIP_FLAGS="--remove-comment"
-               SPLIT_STRIP_FLAGS="-f"
-               ;;
-       *GNU*) # sys-devel/binutils
-               # We'll leave out -R .note for now until we can check out the 
relevance
-               # of the section when it has the ALLOC flag set on it ...
-               SAFE_STRIP_FLAGS="--strip-unneeded -N __gentoo_check_ldflags__"
-               DEF_STRIP_FLAGS="-R .comment -R .GCC.command.line -R 
.note.gnu.gold-version"
-               SPLIT_STRIP_FLAGS=
-esac
-
-read -rd '' -a portage_strip_flags 
<<<"${PORTAGE_STRIP_FLAGS-${SAFE_STRIP_FLAGS} ${DEF_STRIP_FLAGS}}"
-
-prepstrip_sources_dir=${EPREFIX}/usr/src/debug/${CATEGORY}/${PF}
-
-__multijob_init
-
-# Setup ${T} filesystem layout that we care about.
-tmpdir="${T}/prepstrip"
-rm -rf "${tmpdir}"
-mkdir -p "${tmpdir}"/{inodes,splitdebug,sources}
-
 # Atomically writes the standard input to a file whose name is formatted as
 # "estrip-%u.warning", <checksum of input>. The existing contents of the file,
 # if any, shall not be preserved.
@@ -264,8 +56,7 @@ save_elf_sources() {
                "${x}")
 }
 
-# Try to create a symlink.
-# Return success if it already exists.
+# Try to create a symlink. Return success if it already exists.
 __try_symlink() {
        local target=$1
        local name=$2
@@ -399,7 +190,6 @@ save_elf_debug() {
                        fi
                fi
        fi
-
 }
 
 # Usage: process_elf <elf>
@@ -484,6 +274,242 @@ process_ar() {
        fi
 }
 
+get_inode_number() {
+       # Since strip creates a new inode, we need to know the initial set of
+       # inodes in advance, so that we can avoid interference due to trying
+       # to strip the same (hardlinked) file multiple times in parallel.
+       # See bug #421099.
+       if  [[ ${USERLAND} == BSD ]]; then
+               get_inode_number() {
+                       stat -f '%i' "$1"
+               }
+       else
+               get_inode_number() {
+                       stat -c '%i' "$1"
+               }
+       fi
+
+       get_inode_number "$@"
+}
+
+dump_xattrs() {
+       if hash getfattr 2>/dev/null; then
+               dump_xattrs() {
+                       getfattr -d -m - --absolute-names "$1"
+               }
+       else
+               dump_xattrs() {
+                       PYTHONPATH=${PORTAGE_PYTHONPATH:-${PORTAGE_PYM_PATH}} \
+                       "${PORTAGE_PYTHON:-/usr/bin/python}" \
+                       "${PORTAGE_BIN_PATH}/xattr-helper.py" --dump < <(echo 
-n "$1")
+               }
+       fi
+
+       dump_xattrs "$@"
+}
+
+restore_xattrs() {
+       if hash setfattr 2>/dev/null; then
+               restore_xattrs() {
+                       setfattr --restore=-
+               }
+       else
+               restore_xattrs() {
+                       PYTHONPATH=${PORTAGE_PYTHONPATH:-${PORTAGE_PYM_PATH}} \
+                       "${PORTAGE_PYTHON:-/usr/bin/python}" \
+                       "${PORTAGE_BIN_PATH}/xattr-helper.py" --restore
+               }
+       fi
+
+       restore_xattrs "$@"
+}
+
+declare -A has_feature
+declare -A has_restriction
+
+for key in compressdebug dedupdebug installsources nostrip splitdebug xattr; do
+       contains_word "$key" "${FEATURES}"
+       has_feature[$key]=$(( $? == 0 ))
+done
+
+for key in binchecks dedupdebug installsources splitdebug strip; do
+       contains_word "$key" "${PORTAGE_RESTRICT}"
+       has_restriction[$key]=$(( $? == 0 ))
+done
+
+if ! ___eapi_has_prefix_variables; then
+       EPREFIX= ED=${D}
+fi
+
+if (( ! has_restriction[strip] && ! has_feature[nostrip] )); then
+       do_banner=1
+       do_skip=0
+elif (( ! has_feature[installsources] )); then
+       exit 0
+else
+       do_banner=0
+       do_skip=1
+fi
+
+do_prepstrip=0
+
+while [[ $# -gt 0 ]] ; do
+       case $1 in
+       --ignore)
+               shift
+
+               skip_dirs=()
+               for skip; do
+                       if [[ -d ${ED%/}/${skip#/} ]]; then
+                               skip_dirs+=( "${ED%/}/${skip#/}" )
+                       else
+                               rm -f "${ED%/}/${skip#/}.estrip" || die
+                       fi
+               done
+
+               if (( ${#skip_dirs[@]} )); then
+                       find "${skip_dirs[@]}" -name '*.estrip' -delete || die
+               fi
+
+               exit 0
+               ;;
+       --queue)
+               shift
+
+               find_paths=()
+               for path; do
+                       if [[ -e ${ED%/}/${path#/} ]]; then
+                               find_paths+=( "${ED%/}/${path#/}" )
+                       fi
+               done
+
+               if (( ${#find_paths[@]} )); then
+                       # We can avoid scanelf calls for binaries we already
+                       # checked in install_qa_check (where we generate
+                       # NEEDED for everything installed).
+                       #
+                       # EAPI 7+ has controlled stripping (dostrip) though
+                       # which is why estrip has the queue/dequeue logic,
+                       # so we need to take the intersection of:
+                       # 1. files scanned earlier (all ELF installed)
+                       #    (note that this should be a superset of 2., so we 
don't
+                       #    need to worry about unknown files appearing)
+                       #
+                       # 2. the files we're interested in right now
+                       scanelf_results=()
+                       if [[ -f "${PORTAGE_BUILDDIR}"/build-info/NEEDED ]] ; 
then
+                               # The arguments may not be exact files 
(probably aren't), but search paths/directories
+                               # which should then be searched recursively.
+                               while IFS= read -r needed_entry ; do
+                                       for find_path in "${find_paths[@]}" ; do
+                                               # NEEDED has a bunch of entries 
like:
+                                               # /usr/lib64/libfoo.so libc.so
+                                               #
+                                               # find_path entries may be 
exact paths (like /usr/lib64/libfoo.so)
+                                               # or instead /usr/lib64, or 
${ED}/usr, etc.
+                                               #
+                                               # We check if the beginning 
(i.e. first entry) of the NEEDED line
+                                               # matches the path given
+                                               # e.g. find_path="/usr/lib64" 
will match needed_entry="/usr/lib64/libfoo.so libc.so".
+                                               
needed_entry_file="${needed_entry% *}"
+                                               if [[ "${needed_entry_file}" =~ 
^${find_path##"${D}"} ]] ; then
+                                                       scanelf_results+=( 
"${D}${needed_entry_file}" )
+                                               fi
+                                       done
+                               done < "${PORTAGE_BUILDDIR}"/build-info/NEEDED
+                       else
+                               mapfile -t scanelf_results < <(scanelf -yqRBF 
'#k%F' -k '.symtab' "${find_paths[@]}")
+                       fi
+
+                       while IFS= read -r path; do
+                               >> "${path}.estrip" || die
+                       done < <(
+                               (( ${#scanelf_results[@]} )) && printf "%s\n" 
"${scanelf_results[@]}"
+                               find "${find_paths[@]}" -type f ! -type l -name 
'*.a'
+                       )
+
+                       unset scanelf_results needed_entry needed_entry_file 
find_path
+               fi
+
+               exit 0
+               ;;
+       --dequeue)
+               [[ $# -eq 1 ]] || die "${0##*/}: $1 takes no additional 
arguments"
+               break
+               ;;
+       --prepallstrip)
+               [[ $# -eq 1 ]] || die "${0##*/}: $1 takes no additional 
arguments"
+               do_prepstrip=1
+               break
+               ;;
+       *)
+               die "${0##*/}: unknown arguments '$*'"
+               exit 1
+               ;;
+       esac
+       shift
+done
+set -- "${ED}"
+
+[[ ${KERNEL} == linux ]] && (( has_feature[xattr] ))
+do_preserve_xattr=$(( $? == 0 ))
+
+# Determine the names of the tools that might subsequently be used. For several
+# of these, their ${CHOST}-prefixed variants are preferred, if found to exist.
+declare -A name_of
+for bin in debugedit dwz {,"${CHOST}-"}{'objcopy','ranlib','readelf','strip'}; 
do
+       key=${bin#"${CHOST}-"}
+       if [[ ! ${name_of[$key]} ]] || hash "${bin}" 2>/dev/null; then
+               name_of[$key]=${bin}
+       fi
+done
+
+# If debugedit does not exist, consider some alternative locations for it.
+if ! hash "${name_of[debugedit]}" 2>/dev/null; then
+       debugedit_paths=(
+               "${EPREFIX}/usr/libexec/rpm/debugedit"
+       )
+       for x in "${debugedit_paths[@]}"; do
+               if [[ -x ${x} ]]; then
+                       name_of[debugedit]=${x}
+                       break
+               fi
+       done
+fi
+
+# Declare a map to keep track of whether warnings in certain categories have
+# been issued for a missing tool.
+declare -A warned_for
+
+# Figure out what tool set we're using to strip stuff
+unset SAFE_STRIP_FLAGS DEF_STRIP_FLAGS SPLIT_STRIP_FLAGS
+case $("${name_of[strip]}" --version 2>/dev/null) in
+       *elfutils*) # dev-libs/elfutils
+               # elfutils default behavior is always safe, so don't need to 
specify
+               # any flags at all
+               SAFE_STRIP_FLAGS=""
+               DEF_STRIP_FLAGS="--remove-comment"
+               SPLIT_STRIP_FLAGS="-f"
+               ;;
+       *GNU*) # sys-devel/binutils
+               # We'll leave out -R .note for now until we can check out the 
relevance
+               # of the section when it has the ALLOC flag set on it ...
+               SAFE_STRIP_FLAGS="--strip-unneeded -N __gentoo_check_ldflags__"
+               DEF_STRIP_FLAGS="-R .comment -R .GCC.command.line -R 
.note.gnu.gold-version"
+               SPLIT_STRIP_FLAGS=
+esac
+
+read -rd '' -a portage_strip_flags 
<<<"${PORTAGE_STRIP_FLAGS-${SAFE_STRIP_FLAGS} ${DEF_STRIP_FLAGS}}"
+
+prepstrip_sources_dir=${EPREFIX}/usr/src/debug/${CATEGORY}/${PF}
+
+__multijob_init
+
+# Setup ${T} filesystem layout that we care about.
+tmpdir="${T}/prepstrip"
+rm -rf "${tmpdir}"
+mkdir -p "${tmpdir}"/{inodes,splitdebug,sources}
+
 # The existance of the section .symtab tells us that a binary is stripped.
 # We want to log already stripped binaries, as this may be a QA violation.
 # They prevent us from getting the splitdebug data.
@@ -520,16 +546,6 @@ if (( ! has_restriction[binchecks] )); then
        __multijob_post_fork
 fi
 
-# Since strip creates a new inode, we need to know the initial set of
-# inodes in advance, so that we can avoid interference due to trying
-# to strip the same (hardlinked) file multiple times in parallel.
-# See bug #421099.
-if  [[ ${USERLAND} == BSD ]] ; then
-       get_inode_number() { stat -f '%i' "$1"; }
-else
-       get_inode_number() { stat -c '%i' "$1"; }
-fi
-
 cd "${tmpdir}/inodes" || die "cd failed unexpectedly"
 
 if (( do_prepstrip )); then

Reply via email to