# Peter Jones <pjones@redhat.com>
# Jeremy Katz <katzj@redhat.com>
# Jakub Jelinek <jakub@redhat.com>
-#
-#
IF_RTLD=""
IF_dynamic=""
get_dso_deps() {
local bin="$1" ; shift
+ local FILES=() LDSO NAME IO FILE ADDR I1 n f TLIBDIR
- declare -a FILES
- declare -a NAMES
-
- local LDSO=$(LANG=C eu-readelf -l $bin 2>/dev/null |grep interpreter |awk {'print $4;'} |sed -e 's/]$//')
- [ -z "$LDSO" -o "$LDSO" == "$bin" ] && local LDSO="$IF_RTLD"
- [ -z "$LDSO" -o "$LDSO" == "$bin" ] && return 1
- [ -z "$IF_RTLD" ] && IF_RTLD="$LDSO"
+ LDSO=$(LANG=C eu-readelf -l $bin 2>/dev/null | \
+ awk '/interpreter/ {print $4}' |sed -e 's/]$//')
+ [[ $LDSO && $LDSO != $bin ]] || LDSO="$IF_RTLD"
+ [[ $LDSO && $LDSO != $bin ]] || return 1
+ [[ $IF_RTLD ]] || IF_RTLD="$LDSO"
- # I hate shell.
- declare -i n=0
+ # I love bash!
while read NAME I0 FILE ADDR I1 ; do
- [ "$FILE" == "not" ] && FILE="$FILE $ADDR"
- [ "$NAME" == "not" ] && NAME="$NAME $I0"
- NAMES[$n]="$NAME"
- FILES[$n]="$FILE"
- let n++
- done << EOF
- $(LD_TRACE_PRELINKING=1 LD_WARN= LD_TRACE_LOADED_OBJECTS=1 \
+ [[ $FILE = $bin ]] && continue
+ [[ $FILE = not || $NAME = not ]] && {
+ echo "Missing a shared library required by $bin." >&2
+ echo "dracut cannot create an initrd." >&2
+ return 1
+ }
+ # see if we are loading an optimized version of a shared lib.
+ [[ $FILE =~ '(/lib[^/]*).*' ]] && {
+ TLIBDIR=${BASH_REMATCH[1]}
+ BASE="${FILE##*/}"
+ # prefer nosegneg libs, then unoptimized ones.
+ for f in "$TLIBDIR/i686/nosegneg" "$TLIBDIR"; do
+ [[ -f $f/$BASE ]] || continue
+ FILE="$f/$BASE"
+ break
+ done
+ IF_dynamic="yes"
+ }
+ FILES+=("$FILE")
+ done < <(LD_TRACE_PRELINKING=1 LD_WARN= LD_TRACE_LOADED_OBJECTS=1 \
$LDSO $bin 2>/dev/null)
-EOF
-
- [ ${#FILES[*]} -eq 0 ] && return 1
-
- # we don't want the name of the binary in the list
- if [ "${FILES[0]}" == "$bin" ]; then
- FILES[0]=""
- NAMES[0]=""
- [ ${#FILES[*]} -eq 1 ] && return 1
- fi
-
- declare -i n=0
- while [ $n -lt ${#FILES[*]} ]; do
- local FILE="${FILES[$n]}"
- local NAME="${NAMES[$n]}"
- if [ "$FILE" == "not found" -o "$NAME" == "not found" ]; then
- cat 1>&2 <<EOF
-There are missing files on your system. The dynamic object $bin
-requires ${NAMES[$n]} n order to properly function. mkinitrd cannot continue.
-EOF
- return 1
- fi
- case "$FILE" in
- /lib*)
- TLIBDIR=`echo "$FILE" | sed 's,\(/lib[^/]*\)/.*$,\1,'`
- BASE=`basename "$FILE"`
- # Prefer nosegneg libs over direct segment accesses on i686.
- if [ -f "$TLIBDIR/i686/nosegneg/$BASE" ]; then
- FILE="$TLIBDIR/i686/nosegneg/$BASE"
- # Otherwise, prefer base libraries rather than their optimized
- # variants.
- elif [ -f "$TLIBDIR/$BASE" ]; then
- FILE="$TLIBDIR/$BASE"
- fi
- FILES[$n]="$FILE"
- ;;
- esac
- IF_dynamic="yes"
- let n++
- done
echo "${FILES[@]}"
}