#!/bin/sh -efu # # debuginfo.req - soname-based requires for *.debug files # # Written by Alexey Tourbin . Based on lib.req. # License: GPLv2+. . @RPMCONFIGDIR@/functions dump_ld_config='@RPMCONFIGDIR@/dump_ld_config' shlib_req='@RPMCONFIGDIR@/shlib.req.awk' elf_ldd='@RPMCONFIGDIR@/ldd' [ -n "${RPM_LIBDIR-}" ] || RPM_LIBDIR=`rpm --eval %_libdir` [ -n "${RPM_LIB-}" ] || RPM_LIB=`rpm --eval %_lib` [ -n "${RPM_ARCH-}" ] || RPM_ARCH=`rpm --eval %_arch` RPM_FINDREQ_RPATH="/$RPM_LIB $RPM_LIBDIR $("$dump_ld_config")" [ -z "${RPM_BUILD_ROOT-}" ] || RPM_FINDREQ_RPATH="$("$dump_ld_config" '' "$RPM_BUILD_ROOT") $RPM_FINDREQ_RPATH" Debug "RPM_FINDREQ_RPATH=$RPM_FINDREQ_RPATH" not_yet_list= HasDebugInfo() { if readelf --wide --sections "$1" |LC_ALL=C fgrep -qs '.gnu_debuglink'; then return 0 fi if [ -z "$not_yet_list" ] || [ -n "${not_yet_list##* $1 *}" ]; then Warning "$1 is not yet debuginfo-enabled" not_yet_list="$not_yet_list $1 " fi return 1 } DebugInfoReq() { local debugf="$1" local f="${debugf#${RPM_BUILD_ROOT-}/usr/lib/debug}" f="${RPM_BUILD_ROOT-}${f%.debug}" local fname="${f#${RPM_BUILD_ROOT-}}" # Obtain objdump info. local dump if ! dump=$(objdump -p "$f"); then Warning "$f: objdump failed" return 0 fi # Obtain ELF segments. local segments if ! segments=$(readelf --wide --segments "$f"); then Warning "$f: readelf failed" return 0 fi # Interp. local interp interp="$(printf '%s\n' "$segments" | sed -ne 's,^[[:space:]]*\[Requesting program interpreter: \(/[^]]\+\)\]$,\1,p')" if [ -n "$interp" ]; then if [ -n "${RPM_BUILD_ROOT-}" ] && [ -x "$RPM_BUILD_ROOT$interp" ] || HasDebugInfo "$interp"; then printf '/usr/lib/debug%s.debug\n' "$interp" fi fi # That could be "statically linked (uses shared libs)". printf '%s\n' "$dump" |grep -qs '^Dynamic Section:$' || return 0 # The rest is soname stuff. local debug canon_prefix deps dir name pathname prefix rpath suffix vers suffix="$(printf '%s\n' "$dump" |sed -ne 's/^.*file format \(elf64\).*$/(64bit)/p')" [ -z "$suffix" ] && debug=debug || debug=debug64 rpath="$(printf %s "$dump" | awk '($1=="RPATH"||$1=="RUNPATH"){print $2}' | tr -s : ' ' | sed -e "s|\$ORIGIN|${fname%/*}|g")" if [ -n "$rpath" ]; then rpath="$rpath $RPM_FINDREQ_RPATH" else rpath="$RPM_FINDREQ_RPATH" fi rpath="$(printf %s "$rpath" | tr -s '[:space:]' '\n' | grep -v '^$' | LANG=C uniq | sed -e "s|^|${RPM_BUILD_ROOT-}&|" | tr -s '[:space:]' : | sed -e 's/^:\+//; s/:\+$//')" deps="$("$elf_ldd" -- "$f" "$rpath")" || return 1 for vers in `printf '%s\n' "$dump" |"$shlib_req"`; do name="$(printf %s "$vers" |cut -d: -f1)" vers="$(printf %s "$vers" |cut -d: -f2-)" pathname="$(printf %s "$deps" |awk "-vname=$name" ' function basename(f) { sub("^.*/","",f); return f; } NF>=3 && ($1==name || basename($1)==name) && $2=="=>" && $3~"^/" {print $3} NF==2 && ($1==name || basename($1)==name) && $1~"^/" && $2~"^[(]0x" {print $1} ')" if [ -z "$pathname" ]; then Warning "$fname: library $name not found" continue fi pathname=$(CanonPath "$pathname") Verbose "$fname: $name -> $pathname" local under_buildroot= if [ -n "${RPM_BUILD_ROOT-}" ] && [ -z "${pathname##$RPM_BUILD_ROOT*}" ]; then pathname=${pathname#$RPM_BUILD_ROOT} under_buildroot=1 fi prefix="${pathname%/*}" canon_prefix="$(printf %s "$prefix/" | sed -e 's|/tls/|/|' -e 's|/sse2/|/|' -e "s|/$RPM_ARCH/|/|" -e 's|/i[3-9]86/|/|' -e 's|/\+$||')" if [ -z "$canon_prefix" -o -n "${canon_prefix##/*}" ]; then Warning "$fname: library $name not found" continue fi for dir in $RPM_FINDREQ_RPATH; do if [ "$canon_prefix" = "$dir" ]; then prefix= break fi done if [ -n "$under_buildroot" ] || HasDebugInfo "$pathname"; then if [ -z "$prefix" ]; then printf '%s(%s)\n' "$debug" "$name" else printf '/usr/lib/debug%s/%s.debug\n' "$prefix" "${name##*/}" fi fi done } ArgvFileAction DebugInfoReq "$@"