#!/bin/sh
#
# $0 <module> <offset> <sym> <hit>
#
# ie. $0 iffparse.library 0x080e34b0: SeekStream 0x80e5257
#

if [ "$#" -eq 0 ]; then
    echo "$0 module offset sym hit"
    echo "Example: $0 iffparse.library 0x080e34b0: SeekStream 0x80e5257"
    exit 0
fi

path=`dirname $0`
module="$1"
symoffset="$2"
sym="$3"
hitaddr="$4"

if [ ! -e "$module" ]; then
    echo "$0: $module: no such file"
    exit 1
fi

entry=`nm "$module" | egrep " $sym\$"`

if [ -z "$entry" ]; then
    echo "$0: Can't find symbol $sym in $module"
    exit 1
fi

#echo $entry

offset=`echo "0x$entry" | cut "-d " -f1`
offset=`$path/strtoint $offset`

symoffset=`echo $symoffset | gawk ' { if (!match($1,/^0x/)) print "0x"$1; else print $1; }'`
hitaddr=`echo $hitaddr | gawk ' { if (!match($1,/^0x/)) print "0x"$1; else print $1; }'`

symoffset=`$path/strtoint $symoffset`
hitaddr=`$path/strtoint $hitaddr`

baseaddr=`expr $symoffset - $offset`

hitoffset=`expr $hitaddr - $baseaddr`

echo "baseaddr=`printf "%x" $baseaddr`"
echo "hitoffset=`printf "%x" $hitoffset`"

if [ $hitoffset -lt 0 ]; then
    echo "Hit is not in $module"
    exit 1;
fi

objdump --source --line-numbers "$module" | gawk 'BEGIN { \
    lastoff=0; \
    hitoffset='$hitoffset'; \
    found=0; \
    cline[0]=""; \
    cline[1]=""; \
    cline[2]=""; \
    cline[3]=""; \
    file=""; \
    line=0; \
} \
/^[-a-zA-Z0-9_./]+:[0-9]+$/ { \
    split($0,a,":"); \
    file=a[1]; \
    line=int(a[2]); \
} \
/^[ \t]+/ { \
    cline[0]=cline[1]; \
    cline[1]=cline[2]; \
    cline[2]=cline[3]; \
    cline[3]=$0; \
    line ++; \
} \
/^[0-9a-f]+ / { \
    asmline[0]=asmline[1]; \
    asmline[1]=asmline[2]; \
    asmline[2]=asmline[3]; \
    asmline[3]=$0; \
    off=hex2int($1); \
    #print $1"="off; \
    if (lastoff <= hitoffset && off > hitoffset) \
    { \
	if (file!="")
	    printf ("Hit is at line %d in file %s\n", line, file); \
	else
	    printf ("Hit is 0x%x bytes in %s\n", hitoffset-lastoff, symbol); \
	for (t=0; t<4; t++) \
	    print cline[t]; \
	print "        ..."; \
	for (t=0; t<4; t++) \
	    print asmline[t]; \
	for (t=0; t<4; t++) \
	{\
	    getline; \
	    print; \
	} \
	found=1; \
	exit (0); \
    } \
    symbol=$2; \
    lastoff=off; \
} \
END { \
    if (!found) \
    { \
	print "Hit is not in '$module'"; \
	exit (1); \
    } \
} \
\
function hex2int(str    ,x,n) { \
    x=str; \
    n=0; \
    while(x!="") \
    { \
	n=n*16 + index("0123456789abcdef",tolower(substr(x,1,1)))-1; \
	x=substr(x,2); \
    } \
    #print "str="str"  n="n; \
    return n; \
}'
