#!/bin/sh
compute_sizes()
{
objdump -h $BNAME.xko |grep "^  . \.bss" >.tmp
read a b BSSSIZE BSSVMA e BSSFILEOFF g <.tmp
objdump -h $BNAME.xko |grep "^  . \.text" >.tmp
read a b c TEXTVMA e TEXTFILEOFF g <.tmp
TEXTSIZE=$((0x$BSSFILEOFF-0x$TEXTFILEOFF))
SIZE=$((0x$BSSFILEOFF-0x$TEXTFILEOFF+0x$BSSSIZE+256))
if ! [ $? = 0 ] ; then
	echo error in computing 0x$BSSFILEOFF-0x$TEXTFILEOFF+0x$BSSSIZE+256
	exit 1
fi
if [ $SIZE = 0 ] ; then
	echo got SIZE=0
	exit 1
fi
echo SIZE=$SIZE
}

getsymaddr()
{
objdump -x $BNAME.xko |grep " "$1\$ |cut -d " " -f 1 >.sym
if ! [ -s .sym ] ; then
	echo symbol $1 not found 1>&2
	exit 1
fi
SYMADDR=0x`tr -d "\n" <.sym` 
rm -f .sym
}

setparm()
{
sym=`echo -n $1|sed 's/=.*//'`
val=`echo -n $1|sed 's/.*=//'`
if ! ntob $val > .val ; then
	echo invalid value $val
	exit 1
fi
getsymaddr $sym
xenwritemem $SYMADDR $ADDRSIZE .val
if ! [ $? = 0 ] ; then
	echo error writing xen memory
	exit 1
fi
}


if [ X$XENMODDIR = X ] ; then
	echo XENMODDIR not set
	exit 1
fi
export PATH=$XENMODDIR:$PATH
if uname -m |grep -q i.86 ; then
	export ADDRSIZE=4
	export LDSCR=ld.impure
elif uname -m |grep -q x86_64 ; then
	export ADDRSIZE=8
	export LDSCR=ld64.impure
else
	echo unknown ADDRSIZE, fixme...
	exit 1
fi

#if ! [ $# = 1 ] ; then
#	echo gimme one orgument, .o file
#	exit 1
#fi
BNAME=`basename $1 .o`
if ! ld -N -o $BNAME.xko --script=$XENMODDIR/$LDSCR $1 $XENMODDIR/xenlib.o ; then
	exit 1
fi
if ! objdump -x $BNAME.xko | grep -q cleanup_module ; then 
	echo cleanup_module not found
	exit 1
fi
if ! objdump -x $BNAME.xko | grep -q init_module ; then 
	echo init_module not found
	exit 1
fi
compute_sizes
ADDR=`xenalloc $SIZE`
if ! [ $? = 0 ] ; then
	echo error allocating xen memory
	exit 1
fi
echo base=$ADDR
sed "s/0x08048000/$ADDR/g" <$XENMODDIR/$LDSCR > .tmpld
if ! ld -N -o $BNAME.xko --script=.tmpld $1 $XENMODDIR/xenlib.o ; then
	echo error code $?
	exit 1
fi
compute_sizes
dd if=$BNAME.xko bs=1 count=$TEXTSIZE skip=`echo -n $((0x$TEXTFILEOFF))` | \
	xenwritemem 0x$TEXTVMA $TEXTSIZE /proc/self/fd/0
if ! [ $? = 0 ] ; then
	echo error writing xen memory
	exit 1
fi
dd if=/dev/zero bs=1 count=`echo -n $((0x$BSSSIZE))` | \
	xenwritemem 0x$BSSVMA 0x$BSSSIZE /proc/self/fd/0
if ! [ $? = 0 ] ; then
	echo error writing xen memory
	exit 1
fi
shift
while [ $# -gt 0 ] ; do
        setparm $1
        shift
done
getsymaddr init_module
echo xenrunproc $SYMADDR
sync; xenrunproc $SYMADDR
if [ $? = 0 ] ; then
	echo module loaded successfully
	getsymaddr cleanup_module
	echo "$BNAME $SYMADDR" >> $XENMODDIR/.history
	exit 0
else
	echo error loading the module, see xm dmesg
	exit 1
fi




	