This is part of a series of fixes for the linked bug (failure to preserve libraries in some situations).
We need to check if scanelf failed when calling it in the installed-files QA check as we later use it to populate the VDB. Silently continuing results in either blank e.g. PROVIDES, NEEDED{,.ELF.2} or those files may be missing entirely, resulting in a corrupt state both on the system and in any generated binpkgs. Adds an escape variable (PORTAGE_NO_SCANELF_CHECK) to allow re-emerging pax-utils if it's broken. Bug: https://bugs.gentoo.org/811462 Signed-off-by: Sam James <s...@gentoo.org> --- bin/misc-functions.sh | 64 +++++++++++++++++++++++++++++++++---------- 1 file changed, 50 insertions(+), 14 deletions(-) diff --git a/bin/misc-functions.sh b/bin/misc-functions.sh index bd1fb7553..e4defa550 100755 --- a/bin/misc-functions.sh +++ b/bin/misc-functions.sh @@ -177,25 +177,61 @@ install_qa_check() { if type -P scanelf > /dev/null ; then # Save NEEDED information after removing self-contained providers rm -f "$PORTAGE_BUILDDIR"/build-info/NEEDED{,.ELF.2} + # We don't use scanelf -q, since that would omit libraries like # musl's /usr/lib/libc.so which do not have any DT_NEEDED or # DT_SONAME settings. Since we don't use scanelf -q, we have to # handle the special rpath value " - " below. - scanelf -yRBF '%a;%p;%S;%r;%n' "${D%/}/" | { while IFS= read -r l; do - arch=${l%%;*}; l=${l#*;} - obj="/${l%%;*}"; l=${l#*;} - soname=${l%%;*}; l=${l#*;} - rpath=${l%%;*}; l=${l#*;}; [ "${rpath}" = " - " ] && rpath="" - needed=${l%%;*}; l=${l#*;} - - # Infer implicit soname from basename (bug 715162). - if [[ -z ${soname} && $(file "${D%/}${obj}") == *"SB shared object"* ]]; then - soname=${obj##*/} - fi + scanelf_output=$(scanelf -yRBF '%a;%p;%S;%r;%n' "${D%/}/") + + case $? in + 0) + # Proceed + ;; + 159) + # Unknown syscall + eerror "Failed to run scanelf (unknown syscall)" + + if [[ -z ${PORTAGE_NO_SCANELF_CHECK} ]]; then + # Abort only if the special recovery variable isn't set + eerror "Please upgrade pax-utils with:" + eerror " PORTAGE_NO_SCANELF_CHECK=1 emerge -v1 app-misc/pax-utils" + eerror "Aborting to avoid corrupting metadata" + die "${0##*/}: Failed to run scanelf! Update pax-utils?" + fi + ;; + *) + # Failed in another way + eerror "Failed to run scanelf (returned: $?)!" + + if [[ -z ${PORTAGE_NO_SCANELF_CHECK} ]]; then + # Abort only if the special recovery variable isn't set + eerror "Please report this bug at https://bugs.gentoo.org/!" + eerror "It may be possible to re-emerge pax-utils with:" + eerror " PORTAGE_NO_SCANELF_CHECK=1 emerge -v1 app-misc/pax-utils" + eerror "Aborting to avoid corrupting metadata" + die "${0##*/}: Failed to run scanelf!" + fi + ;; + esac + + if [[ -n ${scanelf_output} ]]; then + while IFS= read -r l; do + arch=${l%%;*}; l=${l#*;} + obj="/${l%%;*}"; l=${l#*;} + soname=${l%%;*}; l=${l#*;} + rpath=${l%%;*}; l=${l#*;}; [ "${rpath}" = " - " ] && rpath="" + needed=${l%%;*}; l=${l#*;} + + # Infer implicit soname from basename (bug 715162). + if [[ -z ${soname} && $(file "${D%/}${obj}") == *"SB shared object"* ]]; then + soname=${obj##*/} + fi - echo "${obj} ${needed}" >> "${PORTAGE_BUILDDIR}"/build-info/NEEDED - echo "${arch#EM_};${obj};${soname};${rpath};${needed}" >> "${PORTAGE_BUILDDIR}"/build-info/NEEDED.ELF.2 - done } + echo "${obj} ${needed}" >> "${PORTAGE_BUILDDIR}"/build-info/NEEDED + echo "${arch#EM_};${obj};${soname};${rpath};${needed}" >> "${PORTAGE_BUILDDIR}"/build-info/NEEDED.ELF.2 + done <<< ${scanelf_output} + fi [ -n "${QA_SONAME_NO_SYMLINK}" ] && \ echo "${QA_SONAME_NO_SYMLINK}" > \ -- 2.33.0