141 lines
3.8 KiB
Bash
Executable File
141 lines
3.8 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# pulled right out of mkinitrd....
|
|
DSO_DEPS=""
|
|
LDSO=""
|
|
get_dso_deps() {
|
|
root="$1" ; shift
|
|
bin="$1" ; shift
|
|
LDSODIR="$1" ; shift
|
|
DSO_DEPS=""
|
|
|
|
declare -a FILES
|
|
declare -a NAMES
|
|
[ -z "$LDSODIR" ] && LDSODIR=$LIBDIR
|
|
|
|
# this is a hack, but the only better way requires binutils or elfutils
|
|
# be installed. i.e., we need readelf to find the interpretter.
|
|
$LDSO --verify $bin >/dev/null 2>&1
|
|
case $? in
|
|
[02]) ;;
|
|
*) unset LDSO ;;
|
|
esac
|
|
if [ -z "$LDSO" ]; then
|
|
for ldso in $root/$LDSODIR/ld*.so* ; do
|
|
[ -L $ldso ] && continue
|
|
[ -x $ldso ] || continue
|
|
$ldso --verify $bin >/dev/null 2>&1
|
|
case $? in
|
|
[02]) LDSO=$(echo $ldso |sed -e "s,$root,,") ; break ;;
|
|
esac
|
|
done
|
|
fi
|
|
|
|
# I still hate shell.
|
|
declare -i n=0
|
|
while read NAME I0 FILE ADDR I1 ; do
|
|
[ "$FILE" == "not" ] && FILE="$FILE $ADDR"
|
|
NAMES[$n]="$NAME"
|
|
FILES[$n]="$FILE"
|
|
let n++
|
|
done << EOF
|
|
$(/usr/sbin/chroot $root env LD_TRACE_PRELINKING=1 LD_WARN= \
|
|
LD_TRACE_LOADED_OBJECTS=1 $LDSO $bin)
|
|
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
|
|
FILE="${FILES[$n]}"
|
|
if [ "$FILE" == "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
|
|
exit 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
|
|
;;
|
|
esac
|
|
dynamic="yes"
|
|
let n++
|
|
done
|
|
|
|
DSO_DEPS="${FILES[@]}"
|
|
|
|
for l in $(/usr/sbin/chroot $root find /$LDSODIR -maxdepth 1 -type l -name ld*.so*); do
|
|
[ "$(/usr/sbin/chroot $root readlink -f $l)" == "$LDSO" ] && DSO_DEPS="$DSO_DEPS $l"
|
|
done
|
|
if [ "$(uname -m)" == "s390x" ]; then
|
|
for l in $(/usr/sbin/chroot $root find /lib -maxdepth 1 -type 1 -name ld*.so*); do
|
|
[ "$(/usr/sbin/chroot $root readlink -f $l)" == "$LDSO" ] && DSO_DEPS="$DSO_DEPS $l"
|
|
done
|
|
fi
|
|
|
|
[ -n "$DEBUG" ] && echo "DSO_DEPS for $bin are $DSO_DEPS"
|
|
}
|
|
|
|
instFile() {
|
|
FILE=$1
|
|
DESTROOT=$2
|
|
|
|
[ -n "$DEBUG" ] && echo "Installing $FILE"
|
|
if [ -e $DESTROOT/$FILE -o -L $DESTROOT/$FILE ]; then
|
|
return
|
|
elif [ ! -d $DESTROOT/`dirname $FILE` ]; then
|
|
mkdir -p $DESTROOT/`dirname $FILE`
|
|
fi
|
|
if [ -L $FILE ]; then
|
|
cp -al $FILE $DESTROOT/`dirname $FILE`
|
|
instFile ./`dirname $FILE`/`readlink $FILE` $DESTROOT
|
|
return
|
|
else
|
|
cp -aL $FILE $DESTROOT/`dirname $FILE`
|
|
fi
|
|
|
|
f=$(file $FILE)
|
|
echo $f | egrep -q ": (setuid )?ELF" && {
|
|
if echo $f | grep -q " 64-bit " ; then
|
|
get_dso_deps $(pwd) "$FILE" lib64
|
|
else
|
|
get_dso_deps $(pwd) "$FILE" lib
|
|
fi
|
|
local DEPS="$DSO_DEPS"
|
|
for x in $DEPS ; do
|
|
instFile ./$x $DESTROOT
|
|
done
|
|
}
|
|
unset f
|
|
}
|
|
|
|
instDir() {
|
|
DIR=$1
|
|
DESTROOT=$2
|
|
|
|
[ -n "$DEBUG" ] && echo "Installing $DIR"
|
|
if [ -d $DESTROOT/$DIR -o -h $DESTROOT/$DIR ]; then
|
|
return
|
|
fi
|
|
cp -a --parents $DIR $DESTROOT/
|
|
}
|
|
|