From dbde37aafb6927061fc73a709a58949809dea89e Mon Sep 17 00:00:00 2001 From: Vasiliy Stelmachenok Date: Tue, 24 Dec 2024 18:38:42 +1000 Subject: [PATCH] libmakepkg: strip - split handling of hardlinks Handle singly and muptiply hard-linked files separately. Also collect information on hard linked files to avoid searching the entire package to check for hard links. Signed-off-by: Allan McRae --- scripts/libmakepkg/tidy/strip.sh.in | 99 +++++++++++++++++------------ 1 file changed, 58 insertions(+), 41 deletions(-) diff --git a/scripts/libmakepkg/tidy/strip.sh.in b/scripts/libmakepkg/tidy/strip.sh.in index 949fba86..5eda4b00 100644 --- a/scripts/libmakepkg/tidy/strip.sh.in +++ b/scripts/libmakepkg/tidy/strip.sh.in @@ -103,14 +103,6 @@ collect_debug_symbols() { safe_objcopy "$binary" --remove-section=.gnu_debuglink safe_objcopy "$binary" --add-gnu-debuglink="$dbgdir/${binary#/}.debug" - # create any needed hardlinks - while IFS= read -rd '' file ; do - if [[ "${binary}" -ef "${file}" && ! -f "$dbgdir/${file}.debug" ]]; then - mkdir -p "$dbgdir/${file%/*}" - ln "$dbgdir/${binary}.debug" "$dbgdir/${file}.debug" - fi - done < <(find . -type f -perm -u+w -print0 2>/dev/null) - if [[ -n "$bid" ]]; then local target mkdir -p "$dbgdir/.build-id/${bid:0:2}" @@ -145,6 +137,44 @@ safe_strip_lto() { rm -f "$tempfile" } +process_file_stripping() { + local binary="$1" + local strip_flags + + # skip filepaths that cause stripping issues - ideally these should be temporary + # guile-2.2 + [[ "$binary" =~ .*/guile/.*\.go$ ]] && return + + local STATICOBJ=0 + case "$(LC_ALL=C readelf -h "$binary" 2>/dev/null)" in + *Type:*'DYN (Shared object file)'*) # Libraries (.so) or Relocatable binaries + strip_flags="$STRIP_SHARED";; + *Type:*'DYN (Position-Independent Executable file)'*) # Relocatable binaries + strip_flags="$STRIP_SHARED";; + *Type:*'EXEC (Executable file)'*) # Binaries + if [[ "$(readelf -x .dynamic "$binary" 2>/dev/null)" ]]; then + strip_flags="$STRIP_BINARIES" + else + strip_flags="$STRIP_STATIC" + fi + ;; + *Type:*'REL (Relocatable file)'*) # Libraries (.a) or objects + if [[ $binary = *'.o' ]] || ar t "$binary" &>/dev/null; then + strip_flags="$STRIP_STATIC" + STATICOBJ=1 + elif [[ $binary = *'.ko' ]]; then # Kernel modules + strip_flags="$STRIP_SHARED" + else + return + fi + ;; + *) + return ;; + esac + (( ! STATICOBJ )) && collect_debug_symbols "$binary" + safe_strip_file "$binary" ${strip_flags} + (( STATICOBJ )) && safe_strip_lto "$binary" +} tidy_strip() { if check_option "strip" "y"; then @@ -160,42 +190,29 @@ tidy_strip() { mkdir -p "$dbgdir" "$dbgsrc" fi - local binary strip_flags - find . -type f -perm -u+w -print0 2>/dev/null | LC_ALL=C sort -z | while IFS= read -rd '' binary ; do - # skip filepaths that cause stripping issues - ideally these should be temporary - # guile-2.2 - [[ "$binary" =~ .*/guile/.*\.go$ ]] && continue + while IFS= read -rd '' binary ; do + process_file_stripping "$binary" + done < <(find . -type f -perm -u+w -links 1 -print0 2>/dev/null) - local STATICOBJ=0 - case "$(LC_ALL=C readelf -h "$binary" 2>/dev/null)" in - *Type:*'DYN (Shared object file)'*) # Libraries (.so) or Relocatable binaries - strip_flags="$STRIP_SHARED";; - *Type:*'DYN (Position-Independent Executable file)'*) # Relocatable binaries - strip_flags="$STRIP_SHARED";; - *Type:*'EXEC (Executable file)'*) # Binaries - if [[ "$(readelf -x .dynamic "$binary" 2>/dev/null)" ]]; then - strip_flags="$STRIP_BINARIES" - else - strip_flags="$STRIP_STATIC" - fi - ;; - *Type:*'REL (Relocatable file)'*) # Libraries (.a) or objects - if [[ $binary = *'.o' ]] || ar t "$binary" &>/dev/null; then - strip_flags="$STRIP_STATIC" - STATICOBJ=1 - elif [[ $binary = *'.ko' ]]; then # Kernel modules - strip_flags="$STRIP_SHARED" - else + # hardlinks only need processed once, but need additional links in debug packages + declare -A hardlinks + while IFS= read -rd '' binary ; do + if check_option "debug" "y"; then + local inode="$(@INODECMD@ -- "$binary")" + inode=${inode%% *} + if [[ -z "${hardlinks[$inode]}" ]]; then + hardlinks[$inode]="$binary" + else + if [[ -f "$dbgdir/${hardlinks[$inode]}.debug" ]]; then + mkdir -p "$dbgdir/${binary%/*}" + ln "$dbgdir/${hardlinks[$inode]}.debug" "$dbgdir/${binary}.debug" continue fi - ;; - *) - continue ;; - esac - (( ! STATICOBJ )) && collect_debug_symbols "$binary" - safe_strip_file "$binary" ${strip_flags} - (( STATICOBJ )) && safe_strip_lto "$binary" - done + fi + fi + process_file_stripping "$binary" + done < <(find . -type f -perm -u+w -links +1 -print0 2>/dev/null | LC_ALL=C sort -z) + elif check_option "debug" "y"; then msg2 "$(gettext "Copying source files needed for debug symbols...")"