mirror of
https://github.com/joel16/uofw.git
synced 2024-11-26 21:10:38 +00:00
206 lines
5.5 KiB
Bash
Executable File
206 lines
5.5 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
###
|
|
# This program generates a diff file from different PRX versions, comparing functions with each other.
|
|
# It's very slow, especially for big modules (it can take up to an hour for huge modules, probably)
|
|
# It creates a lot of files in the <PRX file>-diff directory. The most useful created file is "mod.diff", it contains all the differences, including the ones from data.
|
|
####
|
|
|
|
# Generates a list of functions
|
|
function genlist
|
|
{
|
|
local file=$1
|
|
|
|
local i=1
|
|
for f in `cat $file|grep "; Subroutine"|sed -e "s/.*outine //" -e "s/ .*//"`; do
|
|
echo $i $f
|
|
i=$(( $i + 1 ))
|
|
done
|
|
}
|
|
|
|
# Add two matching functions (from old & new PRX) in the matching list
|
|
function match
|
|
{
|
|
list1=`echo "$list1"|grep -v "^$1 "`
|
|
list2=`echo "$list2"|grep -v "^$2 "`
|
|
matchlist[$1]=$2
|
|
echo "$1 <=> $2"
|
|
}
|
|
|
|
# Get a function content
|
|
function getfunc
|
|
{
|
|
file=$1
|
|
func=$2
|
|
start=`cat -n $file|grep "Subroutine.*$func"|sed -e "s/^[^0-9]*//" -e "s/[^0-9].*//"`
|
|
start=`expr $start + 3`
|
|
content=`cat $file|sed -n -e "$start,/; ====/p"`
|
|
echo "$content"|head -n $(( `echo "$content"|wc -l` - 2 ))|sed -e "s/; Refs.*//" -e "s/loc_......../loc/" -e "s/Subroutine sub_......../Subroutine sub/" -e "s/0x........: //" -e "s/Address.*//" -e "s/Data ref.*/Data ref/"
|
|
}
|
|
|
|
# Get data sections from a PRX file
|
|
function getdata
|
|
{
|
|
startaddr=`cat $1|grep ".rodata"|sed -e "s/.*Address //" -e "s/ .*//"`
|
|
startaddr=`printf "%d\n" $startaddr`
|
|
for i in `cat $1|sed -n -e "5,$ p"|sed -n -e "/Section/,$ p"|grep "^0x........ "|sed -e "s/ - ................$//" -e "s/ - /_/" -e "s/ | /|/g" -e "s/ /,/g"`; do
|
|
addr=`echo $i|sed -e "s/_.*//"`
|
|
intv=`printf "%d\n" $addr`
|
|
offset=`expr $intv - $startaddr`
|
|
offset=`printf "0x%08X\n" $offset`
|
|
echo $i|sed -e "s/^0x........_/$offset /" -e "s/,/ /g" -e "s/|/ | /g"
|
|
done
|
|
}
|
|
|
|
if [ $# -ne 2 ]; then
|
|
echo "Usage: ./diff.sh <old> <new>"
|
|
exit 1
|
|
fi
|
|
|
|
echo "diff $1 $2"
|
|
prxtmp1="re1"
|
|
prxtmp2="re2"
|
|
difftmp1="diff1"
|
|
difftmp2="diff2"
|
|
difftmp="diff"
|
|
|
|
dir=`echo $1|sed -e "s/.*\///"`
|
|
dir="$dir-diff"
|
|
|
|
if [ ! -e $dir ]; then
|
|
mkdir $dir
|
|
fi
|
|
|
|
cd $dir
|
|
|
|
if [ ! -f $prxtmp1 ]; then
|
|
prxtool -w $1 > $prxtmp1
|
|
fi
|
|
if [ ! -f $prxtmp2 ]; then
|
|
prxtool -w $2 > $prxtmp2
|
|
fi
|
|
|
|
list1=`genlist $prxtmp1`
|
|
numlist1=`echo "$list1"|wc -l`
|
|
list2=`genlist $prxtmp2`
|
|
numlist2=`echo "$list2"|wc -l`
|
|
|
|
list1back=$list1
|
|
list2back=$list2
|
|
|
|
echo "list 1:"
|
|
echo "$list1"
|
|
echo "list 2"
|
|
echo "$list2"
|
|
|
|
# regroup functions by name
|
|
for num1 in `seq $numlist1`; do
|
|
name=`echo "$list1"|grep "^$num1 "|sed -e "s/[^ ]* //"`
|
|
num2=`echo "$list2"|grep "$name"|sed -e "s/ .*//"`
|
|
if [ -n "$num2" ]; then
|
|
match $num1 $num2
|
|
fi
|
|
done
|
|
|
|
echo "Storing functions"
|
|
|
|
# put each function in a file
|
|
a1=`echo func-1-*`
|
|
a2=`echo func-2-*`
|
|
if [ "$a1" = "func-1-*" ] || [ "$a2" = "func-2-*" ]; then
|
|
for name in `echo "$list1back"|sed -e "s/.* //"`; do
|
|
num=`echo "$list1back"|grep $name|sed -e "s/ .*//"`
|
|
getfunc $prxtmp1 $name > "func-1-$num"
|
|
done
|
|
|
|
for name in `echo "$list2back"|sed -e "s/.* //"`; do
|
|
num=`echo "$list2back"|grep $name|sed -e "s/ .*//"`
|
|
getfunc $prxtmp2 $name > "func-2-$num"
|
|
done
|
|
fi
|
|
|
|
echo "Doing diff"
|
|
|
|
# put each diff in a file
|
|
a=`echo diff-*`
|
|
if [ "$a" = "diff-*" ]; then
|
|
for l1 in `echo "$list1"|sed -e "s/ .*//"`; do
|
|
for l2 in `echo "$list2"|sed -e "s/ .*//"`; do
|
|
diff "func-1-$l1" "func-2-$l2" > diff-$l1-$l2
|
|
done
|
|
done
|
|
fi
|
|
|
|
echo "Regrouping functions by number of differences"
|
|
|
|
# regroup functions by number of differences
|
|
for l1 in `echo "$list1"|sed -e "s/ .*//"`; do
|
|
min=9999999
|
|
found=0
|
|
for l2 in `echo "$list2"|sed -e "s/ .*//"`; do
|
|
numdiff=`wc -l diff-$l1-$l2|sed -e "s/ .*//"`
|
|
numl1=`wc -l func-1-$l1|sed -e "s/ .*//"`
|
|
numl2=`wc -l func-2-$l2|sed -e "s/ .*//"`
|
|
if [ $numdiff -lt `expr \( $numl1 + $numl2 \) \* 9 / 10` ] && [ $numdiff -lt $min ]; then
|
|
min=$numdiff
|
|
min2=$l2
|
|
found=1
|
|
fi
|
|
done
|
|
if [ $found -eq 1 ]; then
|
|
match $l1 $min2
|
|
fi
|
|
done
|
|
|
|
# generate mod.diff
|
|
rm -f mod.diff
|
|
touch mod.diff
|
|
|
|
for num1 in `seq $numlist1`; do
|
|
num2=${matchlist[$num1]}
|
|
if [ ! "$num2" = "" ]; then
|
|
name1=`echo "$list1back"|grep "^$num1 "|sed -e "s/.* //"`
|
|
name2=`echo "$list2back"|grep "^$num2 "|sed -e "s/.* //"`
|
|
if [ ! -f "diff-$num1-$num2" ]; then
|
|
diff "func-1-$num1" "func-2-$num2" > diff-$num1-$num2
|
|
fi
|
|
echo "$name1 <=> $name2"
|
|
if [ "$name1" = "$name2" ]; then
|
|
if [ `cat diff-$num1-$num2|wc -l` -ne 0 ]; then
|
|
echo "; ================================" >> mod.diff
|
|
echo "; $name1" >> mod.diff
|
|
fi
|
|
else
|
|
echo "; ================================" >> mod.diff
|
|
echo "; $name1 renamed to $name2" >> mod.diff
|
|
fi
|
|
|
|
cat diff-$num1-$num2 >> mod.diff
|
|
fi
|
|
done
|
|
|
|
for removed in `echo "$list1"|sed -e "s/ .*//"`; do
|
|
echo "; ================================" >> mod.diff
|
|
name1=`echo "$list1back"|grep "^$removed "|sed -e "s/.* //"`
|
|
echo "; $name1 has been removed" >> mod.diff
|
|
done
|
|
|
|
for added in `echo "$list2"|sed -e "s/ .*//"`; do
|
|
echo "; ================================" >> mod.diff
|
|
name2=`echo "$list2back"|grep "^$added "|sed -e "s/.* //"`
|
|
echo "; $name2 has been added" >> mod.diff
|
|
cat func-2-$added >> mod.diff
|
|
done
|
|
|
|
# diff data
|
|
echo "; ================================" >> mod.diff
|
|
echo "; data" >> mod.diff
|
|
|
|
getdata $prxtmp1 > data1
|
|
getdata $prxtmp2 > data2
|
|
|
|
diff data1 data2 >> mod.diff
|
|
|
|
cd ..
|
|
|