#!/bin/bash2
#
#
# usage: molpatching [vmlinux/System.map] [...]
#

SYMF=""
for x in "$*" ; do
    if [[ $x == -* ]] ; then
	continue;
    fi
    if [ $x ] ; then
	SYMF="$SYMF $x"	
    fi
done
if [ "$SYMF" == "" ] ; then
    SYMF="/boot/System.map /boot/System.map-`uname -r` /usr/src/linux/System.map"
    if [ -d "$MOL_LIB_DIR" ] ; then
	SYMF="$SYMF $MOL_LIB_DIR/modules/System.map*"
    fi
fi

for x in $SYMF ; do
    if [ -f $x -o -L $x ] ; then
	SYMFILES=(${SYMFILES[*]} $x)
    fi
done

PDIR=""
if [ "$MOL_LIB_DIR" != "" ] ; then
    PDIR=$MOL_LIB_DIR/bin/
fi

# The order is IMPORTANT - must equal the definition in runtime.h!
SYMS=( giveup_fpu do_signal_ret flush_hash_page last_task_used_math next_mmu_context handle_mm_fault Hash Hash_mask )

TMPFILE=/tmp/System.map_tmp
rm -f $TMPFILE

####################################################################
# patch_apply System.map
####################################################################

function patch_apply() {
    #
    # Compare the System.map file with /proc/ksyms to make sure the 
    # devious user is not feeding us an irrelevant System.map file.
    #
    $PDIR./symchecker.pl $1

    [ $? -ne 0 ] && return 1;

    GOOD_SYMBOL_FILE=1

    i=0; ERR=0; XERR=0
    while [ $i -lt ${#SYMS[*]} ] ; do
	    S[$i]=`grep ' '${SYMS[$i]}'$' $1` || ERR=1
	    S[$i]=`echo ${S[$i]]} | awk -- '{ print $1 }'`
	    if [ $ERR -eq 1 ] ; then 
		    echo "ERROR: The kernel symbol '${SYMS[$i]}' could not be found"
		    XERR=1; ERR=0
	    fi
	    # echo "  "0x${S[$i]} : ${SYMS[$i]} 
	    let i=$i+1
    done
    [ $XERR -eq 1 ] && return 1

    #
    # Feed the symbols into the patching script...
    #

    echo Patching the kernel...
    $PDIR./mpatch.engine 0x12345678 ${S[*]} 0x87654321
    RET=$?
    if [ $RET -eq 0 -a "$MOL_LIB_DIR" != "" ] ; then 
	cp $1 $MOL_LIB_DIR/modules/System.map.last
    fi
    rm -f $TMPFILE
    exit $RET
}


####################################################################
# main
####################################################################

#
# We can't add 603 support at runtime...
#
PP=`grep cpu /proc/cpuinfo | awk -- '{ print $3 }'`
if [ "$PP" == 603 -o "$PP" == "603e" -o "$PP" == "603ev" ] ; then
    echo
    echo "This machines has a 603 processor. Unfortunately,"
    echo "it is not possible to add MOL support for this machines"
    echo "without recompiling the kernel (with the MOL patch applied)."
    exit 1;
fi

j=0;
while [ $j -lt ${#SYMFILES[*]} ] ; do
    X=${SYMFILES[$j]}
    let j=$j+1

    echo $X | grep ^- > /dev/null
    if [ $? -eq 0 ] ; then
	continue;
    fi
    if [ ! -f $X ] ; then
	echo "The file '$X' could not be found"
	continue
    fi

    # detect vmlinux files by checking the size
    S=`stat $X | grep Size | awk -- '{ print $2 }'`
    if [ $S -ge 700000 ] ; then
	rm -f $TMPFILE
	nm $X | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aU] \)|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort > $TMPFILE
	X=$TMPFILE
    fi

    patch_apply $X
    rm -f $TMPFILE
done

echo "*** Failed applying the MOL-patches to the kernel   ***"

if [ "$GOOD_SYMBOL_FILE" != "1" ] ; then
    echo "*** Try 'startmol vmlinux' or 'startmol System.map' ***"
fi
exit 1;

